3

我试图让 touchesEnded 在一个手势后触发。我已经包含了一个代码片段,其中 touchesBegan 和 touchesEnded 都可以触发。下面的代码有两个奇怪的行为。当我平移它打印开始并刷卡结束。当我触摸画布时,我得到一个开始和两个结束消息。

我尝试删除 touchesBegan 以确保它不会与 touchesEnded 冲突,但行为是相同的。

#import "C4WorkSpace.h"

@implementation C4WorkSpace

-(void)setup
{
    [self addGesture:PAN name:@"pan" action:@"bbb:"];
    [self gestureForName:@"pan"].delaysTouchesBegan = NO;
    [self gestureForName:@"pan"].delaysTouchesEnded = NO;
}

-(void) bbb : (UIGestureRecognizer *) recognizer
{
    if(recognizer.state == UIGestureRecognizerStateEnded)
        C4Log(@"Swipe Ended");
}
-(void) touchesBegan
{
    C4Log(@"Begin");
}
-(void) touchesEnded
{
    C4Log(@"End");
}

@end
4

1 回答 1

4

这是一个直接涉及 UIGestures 的工作方式的问题。delaysTouchesEnded基本上延迟发送消息touchesEnded:withEvent:并将此值设置为并不NO一定意味着将触发事件。

从文档:

如果手势识别器随后识别出它的手势,则取消这些触摸对象(通过 touchesCancelled:withEvent: 消息)。如果手势识别器无法识别其手势,则窗口会在调用视图的 touchesEnded:withEvent: 方法时传递这些对象。将此属性设置为 NO 以在手势识别器分析相同的触摸时将 UITouchPhaseEnded 中的触摸对象传递到视图。

在您的代码片段中,touchesBegan并且touchesEnded实际上并未启用触发。发生的事情是您正在禁用手势是否允许touchesBegantouchesEnded可用于触发的“延迟”。

设置为 NO 时,delaysTouchesBegan会发生以下情况:

  1. 触摸发生
  2. 手势拦截
  3. 手势被识别
  4. touchesBegan实际发生了(因为手势识别)
  5. 没有延迟,touchesBegan火灾

delaysTouchesEnded触发touchesEnded取决于手势是否成功完成......与之前的情况不同,前者总是touchesBegan在手势开始时实际发生。

在这种情况下会发生以下情况:

  1. 手势被识别
  2. 手势成功完成
  3. 手势 CANCELS 触摸发生手势的视图(这是预期的行为UIGestureRecognizer

...touchesEnded发生在:

  1. 手势被识别
  2. 手势未成功完成
  3. touchesEnded被解雇

使用您的代码,如果您按下,请按住手势而不移动您的手指,然后在一段时间后释放touchesEnded。原因是PAN没有成功完成并允许touchesEnded触发。

不同的方法

您正在使用手势,因此您想要发生的任何交互都应该考虑到您正在使用的手势......也就是说,当您开始使用手势时,请尝试根据手势进行思考知道它将介于您正在触摸的视图及其固有touchesBegan的等方法之间。

底线

你的bbb:方法很完美。

使用手势时,通过这样的方法来确定手势的各种状态。这就是您想要使用手势的方式。

试试下面的代码:

#import "C4WorkSpace.h"

@implementation C4WorkSpace
-(void)setup
{
    [self addGesture:PAN name:@"pan" action:@"bbb:"];
    [self gestureForName:@"pan"].delaysTouchesBegan = NO;
    [self gestureForName:@"pan"].delaysTouchesEnded = NO;
}

-(void) bbb : (UIGestureRecognizer *) recognizer {
    if(recognizer.state == UIGestureRecognizerStateBegan) {
        C4Log(@"PAN Begin");
    }
    if(recognizer.state == UIGestureRecognizerStateEnded) {
        C4Log(@"PAN ended");
    }
}

-(void)touchesBegan {
    C4Log(@"A touch began");
}

-(void)touchesEnded {
    C4Log(@"A touch ended");
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    C4Log(@"A touch cancelled");
}

@end

请注意,在您做出手势TOUCH后,事件被取消了?BEGIN这就是为什么touchesEnded永远不会被触发的原因,因为当 GESTURE 开始时,系统会识别出“触摸”并不是真正的触摸,而是真正的手势。

于 2013-10-05T21:01:25.240 回答