天天看点

UILongpressGestureRecognizer,长按之后可以随意在当前view和其父View上移动的问题

不知道你有没有注意到,给一个UIButton添加一个长按手势识别:UILongpressGestureRecognizer,当触发长按之后,你可以随意在这个UIButton的父View上移动手指,也不会停止长按,假如整个屏幕都是UIButton的父View,那么只要你触发了长按,然后不松手就可以随意在整个屏幕上移动,直到抬起手指,这样我觉得很奇怪,明明是给UIButton添加的长按手势,为什么手指离开UIButton之后还算是长按呢?

后来查资料了解到给view添加UILongpressGestureRecognizer,触发长按之后,UILongpressGestureRecognizer的识别范围也会包含其superView。

本来我想ios应该有什么属性或者方法可以设置识别范围可以不包括superView,但是我没找到,后来想只能手动控制了,我就在长按的处理方法中获取当前touch的点,判断是不是在UIButton里,如果不是就设置一个标志变量为NO,那么下回再调用这个方法时就判断这个标志变量,如果是NO,就不做任何处理,但是没有办法真的结束长按手势监听,只是给用户一种假象。代码如下:

-(void)buttonLongPressed:(UILongPressGestureRecognizer *)gestureRecognizer
{
    if (self.isStopLongPressed) {
        if (gestureRecognizer.state == UIGestureRecognizerStateEnded || gestureRecognizer.state == UIGestureRecognizerStateCancelled) {
            self.isStopLongPressed = NO;
        }
        return;
    }
    
    UIButton *button = (UIButton *)gestureRecognizer.view;
    CGPoint point = [gestureRecognizer locationInView:button];
    if (point.x < 0 ||point.y < 0 || point.x >button.frame.size.width ||point.y > button.frame.size.height) {
        self.isStopLongPressed = YES;
        [button setSelected:NO];
        return;
    }
    
    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan:         
            [button setSelected:YES];
            break;
        default:
            break;
    }
}
           

还有一个问题,你会发现触发长按之后,UIButton的高亮状态就会消失,这是因为识别为长按之后就会将UIButton的touch cancel掉,UIButton不会给长按设置highlighted状态,所以我在begin后设置UIButton的selected为YES,移出UIButton后设置为NO,这样就可以实现长按点击的效果了。