我目前正在开发自定义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
答案 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");
}