Добавление контекста в элемент управления UI или NSObject - PullRequest
4 голосов
/ 06 января 2011

Здорово иметь возможность addTarget на UIButton. Мне бы только хотелось, чтобы был какой-то хитрый способ присоединить состояние к UIButton, чтобы при вызове целевого метода я мог волшебным образом извлечь это состояние (любой идентификатор) из отправителя.

Что-то вроде:

[button shoveMyObjectInThere:foo];
[button addTarget:self action:@selector(touchyTouchy:) forControlEvents:UIControlEventTouchUpInside];

Далее:

-(void) touchyTouchy:(id) sender {
    UIButton button = (UIButton*)sender;
    id foo = [button getByObjectBack];
    // do something interesting with foo
}

Было бы замечательно, если бы у UIButton было свойство id-контекста, где разработчики могли бы пихать вещи, но, похоже, это не так. Objective-C - очень динамичный язык, поэтому мне интересно, есть ли какой-нибудь хитрый способ добавить метод или поля к объекту во время выполнения?

Ответы [ 4 ]

5 голосов
/ 10 января 2011

Вы можете попробовать сделать ассоциативную ссылку

#import <objc/runtime.h>

objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy); 
objc_getAssociatedObject(id object, void *key);
0 голосов
/ 06 декабря 2017

Официальным решением является использование свойства "tag":

[self.someMutableArray addObject:foo];
button.tag = self.someMutableArray.count - 1;

[button addTarget:self action:@selector(touchyTouchy:) forControlEvents:UIControlEventTouchUpInside];

Тогда:

-(void) touchyTouchy:(id) sender {
    UIButton button = (UIButton*)sender;
    id foo = self.someMutableArray[button.tag];
    // do something interesting with foo
}

В большинстве случаев вы используете enum или константу длятег, но массив, очевидно, более гибкий.

0 голосов
/ 06 января 2011

Так что я только что сделал быстрый тест и нашел некоторые интересные результаты.

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:@"Hello" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(100, 100, 100, 100);
[self.window addSubview:button];

// ...

- (void)buttonClicked:(id)sender {
    NSLog(@"button clicked %@", [sender class]);
}

Это печатает: button clicked UIRoundedRectButton

Так что кажется, что это должно быть возможно ... По правде говоря, я столкнулся с некоторыми проблемами при создании подкласса UIButton, чтобы получить полный пример, но это выглядит многообещающе. :)

0 голосов
/ 06 января 2011

Как насчет setValue:forKey:, части функции кодирования значения ключа в Objective-C?

...