ios - UIPinchGestureRecognizer 仅用于捏合

标签 ios cocoa-touch uikit uigesturerecognizer uipinchgesturerecognizer

我正在尝试创建一个 UIPinchGestureRecognizer,如果用户张开双指(将手指分开),它就会失败。我知道有一种非常简单的方法可以做到这一点,只需在操作方法中采用识别器的比例,如果它大于 1,则设置一个标志并忽略所有 future 的调用。但是,这对我不起作用,我有其他手势识别器需要此捏合识别器失败,因此我需要它在用户按错误的方向捏合时正确失败。

我试图继承 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 实现设置委托(delegate)

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    if let pinch = gestureRecognizer as? UIPinchGestureRecognizer {
        return pinch.scale < 1
    }
    return true
}

关于ios - UIPinchGestureRecognizer 仅用于捏合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26781373/

相关文章:

iphone - 将联系人存储在 iPhone 自己的应用程序中

iOS/Swift 无法向子类添加手势

ios - 从服务器加载 10,000 多行的 UITableView 的正确方法是什么?

ios - UITableView 添加单元格动画

ios - 如何使 UITableView 行随用户修改的内容动态增长

ios - UIView 如何在 View 之间转换点?

ios - 导入唯一对象时 CoreStore 映射关系

ios - 启用/禁用 TableView 单元格 - iOS - Swift

同一应用程序的 iPhone 和 iPad 版本?

ios - SnapKit更新约束导致冲突