allowableMovement似乎被忽略了

时间:2012-10-30 19:36:32

标签: objective-c ios6 uigesturerecognizer

我的allowableMovement中的UILongPressGestureRecognizer属性似乎被忽略了。我使用Single View Application模板创建了一个新项目(Xcode 4.5.1,iOS 6),并在视图中添加了Long Press Gesture Recognizer。有一个插座和一个动作。这是动作方法的代码:

- (IBAction)longPress:(UILongPressGestureRecognizer *)sender
{    
    if (sender.state == UIGestureRecognizerStatePossible)   NSLog(@"possible");
    if (sender.state == UIGestureRecognizerStateBegan)      NSLog(@"began");
    if (sender.state == UIGestureRecognizerStateChanged)    NSLog(@"changed");    
    if (sender.state == UIGestureRecognizerStateRecognized) NSLog(@"recognized");    
    if (sender.state == UIGestureRecognizerStateCancelled)  NSLog(@"cancelled");
    if (sender.state == UIGestureRecognizerStateFailed)     NSLog(@"failed");

    CGPoint locationInView = [sender locationInView:self.view];

    NSLog(@"long press: allowableMovement= %f, x= %f, y= %f", sender.allowableMovement, locationInView.x, locationInView.y);
}

如果我按下足够长的时间然后松开,我会在日志中找到它:

2012-10-30 20:24:41.449 Long Press[1078:907] began
2012-10-30 20:24:41.455 Long Press[1078:907] long press: allowableMovement= 10.000000, x= 210.500000, y= 99.500000
2012-10-30 20:24:42.880 Long Press[1078:907] recognized
2012-10-30 20:24:42.882 Long Press[1078:907] long press: allowableMovement= 10.000000, x= 208.500000, y= 96.000000

这是我所期待的。

但无论我将allowableMovement设置为(正,负,大,小),一旦状态为UIGestureRecognizerStateBegan,我就可以将手指拖到屏幕上。状态更改为UIGestureRecognizerStateChanged并且频繁更新并且locationInView继续准确跟踪。当我放手时,我得到UIGestureRecognizerStateRecognized状态和最终输出到日志。

类引用表示如果移动超过allowableMovement,则识别器应该失败。为什么allowableMovement属性似乎被忽略了?

2 个答案:

答案 0 :(得分:26)

allowableMovement属性与手势开始后可以拖动的距离无关。它是关于手势开始前你可以移动多远。

从课程参考:

  

当指定时间段(minimumPressDuration)按下允许的手指数(numberOfTouchesRequired)并且触摸不超出允许的移动范围(allowableMovement)时,手势开始(UIGestureRecognizerStateBegan)。

当您将minimumPressDuration设置为高达3秒和allowableMovement之类的高点(如1像素)时,这一点就变得很明显了。如果你的手指完全滚动,手势将无法开始。但是如果你将allowableMovement设置为100,你的手指可以滚动很多,手势就会开始。

这样就像其他属性一样。它们都是关于手势开始所需要的。

答案 1 :(得分:5)

我认为allowableMovement正是出于这个目的。我创建了一个小子类来实现allowableMovementAfterBegan的“预期”行为。

#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>

@interface TDMLongPressGestureRecognizer : UILongPressGestureRecognizer
@property (nonatomic, assign) CGFloat allowableMovementAfterBegan;
@end

@implementation TDMLongPressGestureRecognizer
{
    CGPoint initialPoint;
}

- (instancetype)initWithTarget:(id)target action:(SEL)action
{
    self = [super initWithTarget:target action:action];
    if (self) {
        // Use default value for allowableMovement before touches begin
        _allowableMovementAfterBegan = self.allowableMovement; 
    }
    return self;
}

- (void)reset
{
    [super reset];      
    initialPoint = CGPointZero;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];   
    initialPoint = [self locationInView:self.view];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    if (!CGPointEqualToPoint(initialPoint, CGPointZero))
    {
        CGPoint currentPoint = [self locationInView:self.view];

        CGFloat distance = hypot(initialPoint.x - currentPoint.x, initialPoint.y - currentPoint.y);
        if (distance > self.allowableMovementAfterBegan)
            self.state = UIGestureRecognizerStateFailed;
        }
    }
}