UIControl子类 - 事件调用两次

时间:2011-07-14 07:35:29

标签: objective-c ios subclass uicontrol

我目前正在开发自定义UIControl子类。要跟踪触摸,我使用以下方法:

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
 NSLog(@"Start");
 CGPoint location = [touch locationInView:self];
 if ([self touchIsInside:location] == YES) {
    //Touch Down
    [self sendActionsForControlEvents:UIControlEventTouchDown];
    return YES;
 }
 else {
    return NO;
 }  
}

这可以按预期工作,@“开始”是一次性的。下一步是我用UIControlEventTouchDown添加一个Target和一个Selector。

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

这也有效,并且调用了action:方法。但那是我的问题。该动作被调用两次。我究竟做错了什么?我只使用[self sendActionsForControlEvents:UIControlEventTouchDown];一次,目标操作被调用两次。我的代码出了什么问题?

Sandro Meier

2 个答案:

答案 0 :(得分:11)

一旦调用了事件调度程序,第一次调用action方法就会自动发生:

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

注册处理程序。

所以当你打电话时:

//Touch Down
[self sendActionsForControlEvents:UIControlEventTouchDown];

您正在为您的处理程序(以及其他任何已连接的程序)生成第二次调用。

所以看起来你不需要动作处理程序和beginTracking - 使用一个或另一个。

更新

鉴于你的评论并进一步思考:既然你是UIControl的子类,我想你可能不想为自己注册事件处理程序。

相反,你应该专门使用:

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)cancelTrackingWithEvent:(UIEvent *)event;   // event may be nil if cancelled for non-event reasons, e.g. removed from window

tracking实例变量。

所以我认为你不应该发布事件或听事件。此外,如果它不在您的视图中,它是否真的可以获得beginTrackingWithTouch事件?似乎不会。因此,我认为您不需要进行测试,看看它是否在您的视野中。

因此,我认为可能值得退一步思考您正在尝试做什么并重新阅读UIControl文档。具体做法是:

  

子类注释   您可能希望扩展UIControl子类   有两个原因:

     

观察或修改向目标发送的操作消息   特定事件要执行此操作,请覆盖sendAction:to:forEvent:,   评估传入的选择器,目标对象或UIControlEvents位   掩码,并按要求继续。

     

提供自定义跟踪行为(例如,更改   突出显示外观)为此,请覆盖以下一项或所有内容   方法:beginTrackingWithTouch:withEvent:,   continueTrackingWithTouch:withEvent:endTrackingWithTouch:withEvent:

第一部分是让您的UIControl子类为您的控件的客户端或用户执行非标准的目标操作处理处理(这听起来不像您尝试做的那样,尽管您没有'真的给出了高级别的描述。)

第二部分听起来更像您想要做的事情 - 在UIControl子类中进行自定义跟踪。

答案 1 :(得分:-1)

嗯..检查我的代码是否符合您的目标:

UIContr.h

@interface UIContr : UIControl {

}

@end

UIContr.m

#import "UIContr.h"
@implementation UIContr
- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code.
    }
    return self;
}

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
    NSLog(@"Start");
    CGPoint location = [touch locationInView:self];
    if (CGRectContainsPoint(self.frame, location)) {
        //Touch Down
        [self sendActionsForControlEvents:UIControlEventTouchDown];
        return YES;
    }
    else {
        return NO;
    }  
}

- (void)dealloc {
    [super dealloc];
}
@end

如何在UIViewController中使用:

- (void)viewDidLoad {
    UIContr *c = [[UIContr alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
    [c addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
    c.backgroundColor = [UIColor redColor];
    [self.view addSubview:c];
}

-(void)action:(id)sender{
    NSLog(@"123");
}