我的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
属性似乎被忽略了?
答案 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;
}
}
}