我有一个看似基本的问题,但无法弄明白。
基本问题是:如何以编程方式将一个手势识别器从处理程序置于失败状态,而它位于UIGestureRecognizerStateBegan或UIGestureRecognizerStateChanged?
更详细的解释:我在UIScrollView中有一个用于UIView的长按手势识别器。我做了
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
因为否则一旦用户将手指放在视图中,我就无法滚动滚动视图。它是像safari一样的基本触摸,你可以在一个链接上按住手指,突出链接,但向上或向下滚动 - 然后链接不会突出显示,滚动视图会移动。
我现在可以正常工作,因为这两个手势都被识别了,但如果我可以检测到longpress手势识别器的StateChanged中的移动会更好,如果它超过20像素左右,只需以编程方式使longpress失败。
这可能吗?还是我在错误的地方挖掘?
答案 0 :(得分:4)
我在发布问题后发现的另一个问题..
这就是我现在在手势识别器处理程序中所做的事情:
else if (sender.state == UIGestureRecognizerStateChanged) {
CGPoint newTouchPoint = [sender locationInView:[self superview]];
CGFloat dx = newTouchPoint.x - initTouchPoint.x;
CGFloat dy = newTouchPoint.y - initTouchPoint.y;
if (sqrt(dx*dx + dy*dy) > 25.0) {
sender.enabled = NO;
sender.enabled = YES;
}
}
因此,如果手指在任何方向上移动超过25个像素,将enabled属性设置为NO将使识别器失败。所以这将实现我想要的!
答案 1 :(得分:4)
如果是UILongPressGestureRecognizer
,只需设置其allowableMovement
属性。
UILongPressGestureRecognizer* recognizer = [your recognizer];
recognizer.allowableMovement = 25.0f;
答案 2 :(得分:2)
根据文档,您可以将手势识别器子类化:
在YourPanGestureRecognizer.m中:
#import "YourPanGestureRecognizer.h"
@implementation YourPanGestureRecognizer
- (void) cancelGesture {
self.state=UIGestureRecognizerStateCancelled;
}
@end
在YourPanGestureRecognizer.h中:
#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface NPPanGestureRecognizer: UIPanGestureRecognizer
- (void) cancelGesture;
@end
现在你可以从任何地方打电话
YourPanGestureRecognizer *panRecognizer = [[YourPanGestureRecognizer alloc] initWithTarget:self action:@selector(panMoved:)];
[self.view addGestureRecognizer:panRecognizer];
[...]
-(void) panMoved:(YourPanGestureRecognizer*)sender {
[sender cancelGesture]; // This will be called twice
}
参考:https://developer.apple.com/documentation/uikit/uigesturerecognizer?language=objc