Ios UIPinchGestureRecognitor仅用于pinching out

Ios UIPinchGestureRecognitor仅用于pinching out,ios,cocoa-touch,uikit,uigesturerecognizer,uipinchgesturerecognizer,Ios,Cocoa Touch,Uikit,Uigesturerecognizer,Uipinchgesturerecognizer,我正在尝试创建一个UIPinchGestureRecognitor,如果用户掐出(将手指分开)就会失败。我知道有一种非常简单的方法可以做到这一点,只需在action方法中获取识别器的比例,如果它大于1,则设置一个标志并忽略所有未来的调用。但是,这对我来说不起作用,我有其他的手势识别器,需要这个按压识别器失败,所以当用户按压错误的方向时,我需要它正确地失败 我已尝试将UIPinchGestureRecognizer子类化: @implementation BHDetailPinchGestureR

我正在尝试创建一个UIPinchGestureRecognitor,如果用户掐出(将手指分开)就会失败。我知道有一种非常简单的方法可以做到这一点,只需在action方法中获取识别器的比例,如果它大于1,则设置一个标志并忽略所有未来的调用。但是,这对我来说不起作用,我有其他的手势识别器,需要这个按压识别器失败,所以当用户按压错误的方向时,我需要它正确地失败

我已尝试将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
@实现BHDETAILPINCHGESTURE识别器{
CGF初始距离;
}
#pragma标记-对象生命周期方法
-(id)initWithTarget:(id)目标操作:(SEL)操作{
self=[super initWithTarget:target action:action];
如果(自我){
initialDistance=NSNotFound;
}
回归自我;
}
#pragma标记-UIgestureRecognitor方法
-(BOOL)应该需要IlbyGestureRecognitor:(UIGestureRecognitor*)识别器{
if([识别器是类的种类:[UIPinchGestureRecognizer类]]){
return[self.delegate gestureRecognitzershouldBegin:self];
}否则返回false;
}
-(无效)重置{
[超级重置];
initialDistance=NSNotFound;
}
#pragma标记-触摸处理方法
-(无效)触摸开始:(NSSet*)触摸事件:(UIEvent*)事件{
如果(touchs.count>=2){
if(self.state==UIgestureRecognitizerStateEnabled){
//保持接触之间的距离
NSArray*bothTouches=[接触所有对象];
CGPoint location1=[(UITouch*)两个触摸屏[0]locationInView:self.view];
CGPoint location2=[(UITouch*)两个触摸屏[1]locationInView:self.view];
初始距离=[点:位置1和点:位置2之间的自距离];
}
}否则{
//如果只有一次触摸,则失败
self.state=UIgestureRecognitizerStateFailed;
}
}
-(无效)触摸移动:(NSSet*)触摸事件:(UIEvent*)事件{
NSLog(@“Moved.(tc,%lu)(state,%i)(id,%f)”,(unsigned long)touchs.count,self.state,initialDistance);
如果(touchs.count>=2){
if(self.state==UIgestureRecognitizerStateEnabled){
if(初始距离!=NSNotFound){
//获取新距离,然后查看是大于还是小于原始距离
NSArray*bothTouches=[接触所有对象];
CGPoint location1=[(UITouch*)两个触摸屏[0]locationInView:self.view];
CGPoint location2=[(UITouch*)两个触摸屏[1]locationInView:self.view];
NSLog(@“检查点之间的距离”);
if([点:位置1和点:位置2之间的自距离]<初始距离-3.f){
NSLog(@“开始”);
self.state=UIgestureRecognitizerStateStart;
}else if([点:位置1和点:位置2之间的自距离]>初始距离){
NSLog(@“失败”);
self.state=UIgestureRecognitizerStateFailed;
}
}
}否则{
self.state=UIGestureRecognizerStateChanged;
}
}
}
-(void)touchesend:(NSSet*)toucheevent:(UIEvent*)event{
如果(self.state==UIGestureRecognizerStateEnabled)self.state=UIGestureRecognizerStateFailed;
else[超级触控解除:触控事件:事件];
}
-(无效)触控取消:(NSSet*)触控事件:(UIEvent*)事件{
self.state=UIgestureRecognizerStateConcelled;
}
#pragma-mark-Helper方法
-(CGFloat)点:(CGPoint)点1和点:(CGPoint)点2之间的距离{
返回sqrtf(powf(point1.x-point2.x,2)+powf(point1.y-point2.y,2));
}
@结束
我已经意识到,这并不是那么简单,它需要处理多个触摸,有时移动的触摸只有一个触摸,所以它需要保持触摸,一个触摸可能结束,另一个开始,这仍然是捏的一部分。当我想做的只是让它在用户错误的方向挤压时失败时,我似乎失去了挤压识别器的内置功能


有没有一种更简单的方法可以在不完全重写UIPinchGestureRecognitor的情况下实现这种行为?可能值得一提的是,我无法控制我想要失败的其他识别器(它们深藏在PSPDViewController(第三方库)的碗中)。

使用手势识别器的
委托
来帮助如何

使用以下
手势识别器shouldBegin

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    if let pinch = gestureRecognizer as? UIPinchGestureRecognizer {
        return pinch.scale < 1
    }
    return true
}
func-gesturecognizer应该开始(gesturecognizer:uigesturecognizer)->Bool{
如果let pinch=手势识别器as?uipinch手势识别器{
返回1.0刻度<1
}
返回真值
}

我要试一试!我曾认为,在调用此委托方法时,比例将为1,或某个未定义的值。。。请稍等…刻度已设置,尽管这不会“失败”您的手势,只是不会“开始”一个。不过,您可以添加代码使其失败。这非常有效!非常感谢!这样一个简单而优雅的解决方案。似乎我不需要它失败,我只需要它不承认。