Как назначить имя для элемента управления и получить его в методе события? - PullRequest
2 голосов
/ 11 декабря 2008

У меня есть IBAction, такой как:

- (IBAction)showPicker:(id)sender;

Как я могу получить имя элемента управления из переменной отправителя?

Я, как правило, кодер c #, поэтому безуспешно пробовал следующее

senderName = ((UIButton *)sender).name;

Мне нужно что-то более наглядное, чем контрольный идентификатор (не название кнопки). У меня есть 5 кнопок, вызывающих один и тот же метод. Мне нужно определить, на какую из них нажимали, чтобы выполнить действия методов на соответствующем элементе управления. I.E У меня есть метод выбора адреса, но я хочу заполнить 5 текстовых полей различной информацией с помощью каждой из 5 кнопок. Просто пытаюсь сохранить код в чистоте

N.B. Первоначально я планировал использовать поле имени Interface Builders, но мне сообщили (ниже), что это недоступно во время выполнения.

Ответы [ 6 ]

5 голосов
/ 11 декабря 2008

Возможно, вы захотите посмотреть, используя свойство tag . Это целое число, а не имя, но его можно использовать для различения двух элементов управления. Он унаследован от UIView, поэтому любой элемент управления, отправляющий событие, должен иметь его.

Это можно редактировать в Интерфейсном Разработчике в разделе Просмотр атрибутов.

Это свойство, поэтому к нему можно получить программный доступ с точечной нотацией:

control.tag

Или вы можете преобразовать в строку следующим образом:

[stringWithFormat:@"%d", control.tag]
3 голосов
/ 21 февраля 2012

Хотя я согласен, что тег будет работать во многих обстоятельствах, работать с целочисленными тегами очень сложно, когда у вас есть матрица из 100 кнопок, которые можно нажимать там, где вы хотите определить: (1) что было нажато и (2) что значение было сдвинуто. Я начал изобретать схемы именования строк / столбцов с номерами тегов, которые вышли из-под контроля.

Я хотел, чтобы несколько элементов управления совместно использовали один и тот же обработчик, и я хотел тщательно спроектировать свой пользовательский интерфейс в IB для передачи пар имя / значение в хранилище ключ-значение на основе того, что было отправлено.

В качестве альтернативы тегам я предложил другой обходной путь для UISegmentedControl (он работает и для других элементов управления).

(1) Создайте новый класс и подкласс UISegmentedControl. Добавьте строковое свойство MyCustomKey в ваш новый класс.

@interface CustomSegmentedControl : UISegmentedControl
@property (nonatomic, retain) NSString* myCustomKey; 
@end

(2) Вернувшись в IB, измените ваши экземпляры UISegmentedContol, чтобы они были экземплярами CustomSegmentedControl. Использовал IB «Определенные пользователем атрибуты времени выполнения», чтобы установить значение myCustomKey с помощью IB. KeyValueCoding позаботится о настройке свойств для вас:

screen shot of setting your custom property through interface building

(3) Подключите все свои кнопки к одному IBAction.

(4) Теперь в вашем IBAction вы можете извлечь пары ключ-значение, прочитав свой пользовательский атрибут:

- (IBAction)myButtonPressed:(id) sender
{
    if ([sender isKindOfClass:[CustomSegmentedControl class]] == false)
        return;

    // get the key-values from the control
    CustomSegmentedControl *control = (CustomSegmentedControl *)sender;
    NSString *key = [control valueForKey:@"myCustomKey"];
    NSNumber *value = [NSNumber numberWithInteger:[control selectedSegmentIndex]];
    NSLog(@"Pressed control %@ with a value of %@", key, value);
}

В этом случае меня интересовало только целочисленное значение сегментированного элемента управления, но вы могли получить любое свойство из элемента управления в качестве значения.

Надеюсь, это поможет.

3 голосов
/ 11 декабря 2008

Вы не используете имя объекта в Интерфейсном Разработчике для ссылки на этот объект; это просто для справки. (Интерфейсный конструктор также будет использовать его как подсказку для того, какие выходы, подключающиеся к элементу управления, и действия, отправленные элементом управления, могут быть названы, но только как подсказка.)

Вместо этого вы добавляете выход к объекту контроллера, который подключаете к объекту. Это позволяет получить доступ к объекту непосредственно во время выполнения с вашего контроллера, не выполняя никаких действий по поиску.

Кроме того, звучит так, как будто у вас есть пять кнопок с пятью действиями, которые все связаны с одним и тем же методом действия. Не делай этого.

В Cocoa и Cocoa Touch обычно не следует создавать методы действия «для каждого события», а затем решать, что делать в зависимости от того, какой элемент управления отправил событие. Элементы управления в Какао сами обрабатывают события и переводят их в действия более высокого уровня. Таким образом, вы можете реализовать пять методов действия в своем контроллере, подключить каждую кнопку к соответствующему методу действия, и вам никогда не придется решать, что делать в зависимости от того, какой элемент управления отправил действие.

Очевидно, что это не подходит для всех случаев. Например, если у вас есть матрица кнопок с изображениями, которые меняются во время выполнения, вы, вероятно, захотите, чтобы все они подключались к одному действию и различали их по свойству тега. Хорошее эмпирическое правило - использовать разные методы действия при работе с «разными» вещами, а также использовать один и тот же метод действия и контрольные теги при работе с «множеством одинаковых» вещей.

2 голосов
/ 11 декабря 2008

Поле name в Interface Builder Identity является чем-то уникальным для Interface Builder; На самом деле я не совсем уверен, как именно он используется, но он не отображается на пригодное для использования свойство, ivar или метод на вашем фактическом контроле. Вместо этого используйте свойство tag (в атрибутах View), чтобы отличать различные элементы управления от метода действия, если в противном случае вы не оставите ссылку на них как на ivar. Если я вас неправильно понимаю, и вам нужен заголовок кнопки, просто используйте currentTitle.

0 голосов
/ 11 декабря 2008

Попробуйте:

senderTitle = [sender currentTitle];
0 голосов
/ 11 декабря 2008

Если элемент управления имеет атрибут name, то:

NSString *senderName = [sender name];

Это не то, что есть у большинства элементов управления. Вы можете захотеть:

NSString *senderName = [sender title];

Если это был NSButton, например. Или, как говорит Марк, для кнопки UIB используйте currentTitle.

...