UIPinchGestureRecognizer仅适用于捏出
问题描述:
我试图创建一个UIPinchGestureRecognizer,如果用户捏出(移动手指分开)失败。我知道有一种非常简单的方法可以通过在操作方法中采用识别器的比例来实现这一点,并且如果它大于1,则设置一个标记并忽略所有未来呼叫。但是,这对我不起作用,我有其他手势识别器需要此捏夹识别器失败,所以我需要它在用户捏住错误方向时正常失败。UIPinchGestureRecognizer仅适用于捏出
我试图继承UIPinchGestureRecognizer:
@implementation BHDetailPinchGestureRecogniser {
CGFloat initialDistance;
}
#pragma mark - Object Lifecycle Methods
- (id)initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self) {
initialDistance = NSNotFound;
}
return self;
}
#pragma mark - UIGestureRecogniser Methods
- (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)recogniser {
if ([recogniser isKindOfClass:[UIPinchGestureRecognizer class]]) {
return [self.delegate gestureRecognizerShouldBegin:self];
} else return false;
}
- (void)reset {
[super reset];
initialDistance = NSNotFound;
}
#pragma mark - Touch Handling Methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (touches.count >= 2) {
if (self.state == UIGestureRecognizerStatePossible) {
// Keep hold of the distance between the touches
NSArray *bothTouches = [touches allObjects];
CGPoint location1 = [(UITouch *)bothTouches[0] locationInView:self.view];
CGPoint location2 = [(UITouch *)bothTouches[1] locationInView:self.view];
initialDistance = [self distanceBetweenPoint:location1 andPoint:location2];
}
} else {
// Fail if there is only one touch
self.state = UIGestureRecognizerStateFailed;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"Moved. (tc, %lu) (state, %i) (id, %f)", (unsigned long)touches.count, self.state, initialDistance);
if (touches.count >= 2) {
if (self.state == UIGestureRecognizerStatePossible) {
if (initialDistance != NSNotFound) {
// Get the new distance and see if is is larger or smaller than the original
NSArray *bothTouches = [touches allObjects];
CGPoint location1 = [(UITouch *)bothTouches[0] locationInView:self.view];
CGPoint location2 = [(UITouch *)bothTouches[1] locationInView:self.view];
NSLog(@"Checking distance between points.");
if ([self distanceBetweenPoint:location1 andPoint:location2] < initialDistance - 3.f) {
NSLog(@"Began");
self.state = UIGestureRecognizerStateBegan;
} else if ([self distanceBetweenPoint:location1 andPoint:location2] > initialDistance) {
NSLog(@"Failed");
self.state = UIGestureRecognizerStateFailed;
}
}
} else {
self.state = UIGestureRecognizerStateChanged;
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.state == UIGestureRecognizerStatePossible) self.state = UIGestureRecognizerStateFailed;
else [super touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
self.state = UIGestureRecognizerStateCancelled;
}
#pragma mark - Helper Methods
- (CGFloat)distanceBetweenPoint:(CGPoint)point1 andPoint:(CGPoint)point2 {
return sqrtf(powf(point1.x - point2.x, 2) + powf(point1.y - point2.y, 2));
}
@end
我已经意识到,它不是那么简单,它需要处理多点触摸,有时只会接触移动有一个触摸,因此将需要保持保持触动,一触即可结束,另一个开始,这仍然要成为捏的一部分。看起来好像我放松了夹点识别器的功能构建,当我想要做的就是如果用户捏在错误的方向上使它失败。
有没有一种更简单的方法来实现这种行为,而不必完全重写UIPinchGestureRecognizer?可能值得一提的是,我无法控制我想失败的其他识别器(它们深入到PSPDFViewController(第三方库)的碗中)。
答
如何使用手势识别器的delegate
提供帮助?
设置一个委托具有以下实现的gestureRecognizerShouldBegin
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if let pinch = gestureRecognizer as? UIPinchGestureRecognizer {
return pinch.scale < 1
}
return true
}
我给它一个去!我曾经想过,在这个委托方法被调用的时候,比例尺会是1,或者是一些未定义的值...只需一秒... – 2014-11-06 14:21:26
虽然这不会“失败”,但不会“失败” '开始'一个。您可能可以添加代码以使其失败。 – 2014-11-06 14:22:54
这完美的作品!非常感谢!这种简单而优雅的解决方案。看起来我不需要它失败,我只是需要它不承认。 – 2014-11-06 14:24:15