Как реализовать механизм целевого действия для пользовательского контроля?
Я собираюсь написать собственный собственный элемент управления, который сильно отличается от UIButton. Это так сильно отличается от того, что я решил написать его с нуля. Таким образом, все подклассы UIControl.
Когда мой контроль коснулся внутри, тогда я хочу запустить сообщение в виде целевого действия. Пользователь этого класса может создать экземпляр, а затем добавить некоторые цели и действия для этого события.
то есть. Представьте, что я бы назвал внутренне метод -fireTargetsForTouchUpEvent. Как я могу поддерживать этот механизм действия-действия в своем классе? Должен ли я добавлять все цели и действия в свой собственный массив, а затем просто вызывать селектор (действия) целевых объектов в цикле? Или есть более интеллектуальный способ сделать это?
Я предполагаю, что предлагаю некоторые методы для добавления целей и действий для некоторых событий, таких как событие соприкосновения (я поднимаю это вручную, вызывая внутренний метод, когда это произойдет). Любая идея?
Ответы
Ответ 1
Поскольку вы планируете подкласс UIControl, вы можете просто использовать
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
Используя это, любой класс может зарегистрировать себя как цель для любых событий, которые он хочет на вашем настраиваемом контроллере.
Ответ 2
Я просто хочу уточнить, что сказал @Феликсис, потому что сначала мне было непонятно.
Если вы подклассифицируете UIControl
, даже если у вас будет настраиваемое событие, вам не нужно отслеживать свои собственные цели/действия. Функциональность уже существует, все, что вам нужно сделать, - вызвать код ниже в вашем подклассе для запуска события:
[self sendActionsForControlEvents:UIControlEventValueChanged];
Затем в контроллере представления или представления, который создает экземпляр UIControl
, просто выполните
[customControl addTarget:self action:@selector(whatever) forControlEvents:UIControlEventValueChanged];
Для настраиваемого события просто укажите собственное перечисление (например, UIControlEventValueChanged
равно 1 << 12
). Просто убедитесь, что он находится в допустимом диапазоне, определяемом UIControlEventApplicationReserved
Ответ 3
У вас есть правильная идея. Вот как я это сделаю:
@interface TargetActionPair : NSObject
{
id target;
SEL action;
}
@property (assign) id target;
@property (assign) SEL action;
+ (TargetActionPair *)pairWithTarget:(id)aTarget andAction:(SEL)selector;
- (void)fire;
@end
@implementation TargetActionPair
@synthesize target;
@synthesize action;
+ (TargetActionPair *)pairWithTarget:(id)aTarget andAction:(SEL)anAction
{
TargetActionPair * newSelf = [[self alloc] init];
[newSelf setTarget:aTarget];
[newSelf setAction:anAction];
return [newSelf autorelease];
}
- (void)fire
{
[target performSelector:action];
}
@end
С этим классом место хранения ваших целевых/активных пар довольно просто:
MyCustomControl.h:
#import "TargetActionPair.h"
@interface MyCustomControl : UIControl
{
NSMutableArray * touchUpEventHandlers;
}
- (id)init;
- (void)dealloc;
- (void)addHandlerForTouchUp:(TargetActionPair *)handler;
@end
MyCustomControl.m:
#import "TargetActionPair.h"
@implementation MyCustomControl
- (id)init
{
if ((self = [super init]) == nil) { return nil; }
touchUpEventHandlers = [[NSMutableArray alloc] initWithCapacity:0];
return self;
}
- (void)dealloc
{
[touchUpEventHandlers release];
}
- (void)addHandlerForTouchUp:(TargetActionPair *)handler
{
[touchUpEventHandlers addObject:handler];
}
- (void) fireTargetsForTouchUpEvent
{
[touchUpEventHandlers makeObjectsPerformSelector:@selector(fire)];
}
@end
После этого настройка элемента управления будет выполнена следующим образом:
[instanceOfMyControl addHandlerForTouchUp:
[TargetActionPair pairWithTarget:someController
andAction:@selector(touchUpEvent)];