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

16 iphone cocoa-touch uikit

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

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

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

我想提供一些方法来为某些事件添加目标和动作,比如触摸事件(我在发生这种情况时通过调用内部方法手动提升).任何的想法?

pix*_*eak 39

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

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

[self sendActionsForControlEvents:UIControlEventValueChanged];

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

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

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


e.J*_*mes 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
Run Code Online (Sandbox Code Playgroud)

有了这个类,存储目标/动作对非常简单:

MyCustomControl.h:

#import "TargetActionPair.h"

@interface MyCustomControl : UIControl
{
    NSMutableArray * touchUpEventHandlers;
}

- (id)init;
- (void)dealloc;

- (void)addHandlerForTouchUp:(TargetActionPair *)handler;

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

之后,设置控件将按如下方式完成:

[instanceOfMyControl addHandlerForTouchUp:
         [TargetActionPair pairWithTarget:someController
                                andAction:@selector(touchUpEvent)];
Run Code Online (Sandbox Code Playgroud)


Fel*_*xyz 5

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

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
Run Code Online (Sandbox Code Playgroud)

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