如何实现自定义控制的目标 - 动作机制?

时间:2009-08-17 16:22:26

标签: iphone cocoa-touch uikit

我要编写自己的自定义控件,它与UIButton非常不同。这是多么不同,我决定从头开始编写它。所以我所有的子类都是UIControl。

当我的控制被内部触及时,我想以目标动作的方式发出消息。该类的用户可以实例化它,然后为此事件添加一些目标和操作。

即。想象一下,我会在内部调用一个方法-fireTargetsForTouchUpEvent。我怎样才能在班上维护这个目标 - 行动机制?我是否必须将所有目标和操作添加到我自己的数组中,然后在for循环中调用目标对象上的选择器(操作)?或者有更智能的方法吗?

我想提供一些方法来为某些事件添加目标和操作,例如触摸事件(我在发生这种情况时通过调用内部方法手动提升)。有什么想法吗?

3 个答案:

答案 0 :(得分:39)

我只想澄清@Felixyz所说的内容,因为我一开始并不清楚。

如果您是UIControl的子类,即使您要进行自定义事件,也不必跟踪自己的目标/操作。功能已经存在,您所要做的就是调用子类中的以下代码来触发事件:

[self sendActionsForControlEvents:UIControlEventValueChanged];

然后在实例化自定义UIControl的视图或视图控制器中,执行

[customControl addTarget:self action:@selector(whatever) forControlEvents:UIControlEventValueChanged];

对于自定义事件,只需定义自己的枚举(例如,UIControlEventValueChanged等于1 << 12)。只需确保它在UIControlEventApplicationReserved

定义的允许范围内

答案 1 :(得分:15)

你有正确的想法。我将如何做到这一点:

@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)];

答案 2 :(得分:5)

由于您计划子类化UIControl,您可以使用

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

使用它,任何类都可以将自己注册为自定义控制器上任何事件的目标。