UISwipeGestureRecognizer 在不应该执行的 if/else 语句中执行

Posted

技术标签:

【中文标题】UISwipeGestureRecognizer 在不应该执行的 if/else 语句中执行【英文标题】:UISwipeGestureRecognizer executes in an if/else statement when it should not 【发布时间】:2013-12-30 01:08:42 【问题描述】:

当用户滑动屏幕的左半部分时,我正在尝试在 ios 7 Sprite Kit 中运行一个动作。

为了实现这一点,我创建了一个等待触摸事件的 for 循环,并且在触摸时,有一个 if 语句检查触摸位置是否小于视图边界的一半。 if 语句本身正在正确执行(如果在屏幕的右半部分启动触摸,则 else 半部分返回正确的 NSLog)。然而,由 UISwipeGestureRecognizer 触发的操作会被调用,而不管触摸是从哪里开始的。我在下面包含了一个代码示例。

这没有按预期工作是有原因的吗?

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
[super touchesBegan:touches withEvent:event];
for (UITouch *touch in touches) 
    CGPoint touchLocation = [touch locationInView:self.view];
    NSLog(@"Touch location: %f, %f",touchLocation.x,touchLocation.y);

    if (touchLocation.x<self.view.bounds.size.width/2) 
        UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:(self) action:@selector(screenSwipedRight)];
        swipeRight.numberOfTouchesRequired = 1;
        swipeRight.direction=UISwipeGestureRecognizerDirectionRight;
        [self.view addGestureRecognizer:(swipeRight)];

        UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:(self) action:@selector(screenSwipedLeft)];
        swipeLeft.numberOfTouchesRequired = 1;
        swipeLeft.direction=UISwipeGestureRecognizerDirectionLeft;
        [self.view addGestureRecognizer:(swipeLeft)];

        UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:(self) action:@selector(screenSwipedUp)];
        swipeUp.numberOfTouchesRequired = 1;
        swipeUp.direction=UISwipeGestureRecognizerDirectionUp;
        [self.view addGestureRecognizer:(swipeUp)];
    
    else 
        NSLog(@"Touches were on the right!");
    




-(void)screenSwipedRight

    CGFloat percentToRight = 1-(self.playerOne.position.x / self.view.bounds.size.width);
    NSTimeInterval timeToRight = self.horizontalRunSpeed * percentToRight;
    NSLog(@"Percent to right = %f",percentToRight);
    NSLog(@"Time to right = %f",timeToRight);
    SKAction *moveNodeRight = [SKAction moveToX:self.view.bounds.size.width-self.playerOne.size.width duration:timeToRight];
    [self.playerOne runAction:[SKAction sequence:@[moveNodeRight]]];

【问题讨论】:

【参考方案1】:

这没有按预期工作是有原因的吗?

是的。每当屏幕左半部分开始有任何触摸时,您都将添加一组新的滑动手势识别器。你永远不会删除它们。您永远不会限制手势识别器开始的条件。

这应该可以解决您的问题:

    删除touchesBegan:withEvent: 的实现。 在viewDidLoad 中添加您的手势识别器。 为所有手势识别器设置delegate = self

    添加此代码:

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
        CGPoint touchLocation = [touch locationInView:self.view];
        NSLog(@"Touch location: %f, %f",touchLocation.x,touchLocation.y);
        BOOL shouldBegin = (touchLocation.x < self.view.bounds.size.width / 2);
        return shouldBegin;
    
    

【讨论】:

被触发的“动作”是每个手势识别器第一行末尾的选择器。代码示例中包含的示例是“screenSwipedRight”。如果我将手势识别器移动到 viewdidload(视图控制器),我可以从 MyScene.m 调用方法吗? 糟糕,我忘记向右滚动了。菜鸟失误。是的,只需将“目标”从 self 更改为您的 MyScene 实例。 当你的场景发生变化时,你可以使用addTarget:action:removeTarget:action:来更新哪个场景应该知道它,甚至可以通知多个场景。使用 remove 时,为 target 传递 nil 匹配所有目标,为 action 传递 NULL 匹配所有操作。 我不会在viewWillLayoutSubviews 中创建手势识别器,因为如果状态栏大小发生变化或视图旋转,它将被调用。所以你最终可能会得到很多相同的副本。 我将把它作为一个单独的问题发布,因为它可能与创建 MyScene 对象有关,而不是与滑动手势识别器/触摸事件有关。

以上是关于UISwipeGestureRecognizer 在不应该执行的 if/else 语句中执行的主要内容,如果未能解决你的问题,请参考以下文章

识别用户剪切/滑动手势 (UISwipeGestureRecognizer)

UISwipeGestureRecognizer 滑动长度

UISwipeGestureRecognizer 只有一个方向工作

如何检测 UISwipeGestureRecognizer 的结束?

如何使 UISwipeGestureRecognizer 在 UIScrollView 中工作

UISwipeGestureRecognizer 没有触发