ios事件冲突处理

多手势冲突

当两个手势绑定在不同的view上,当滑动两个View公共区域时,只能响应上面view的手势。

1.如何使两个手势都响应?

自定义一个手势以UIPanGestureRecognizer为例。使用UIGestureRecognizer的代理方法

代码

#import <UIKit/UIKit.h>

@interface GestureOne : UIPanGestureRecognizer<UIGestureRecognizerDelegate>

@end


#import "GestureOne.h"

@implementation GestureOne

- (instancetype)initWithTarget:(id)target action:(SEL)action{
    self = [super initWithTarget:target action:action];

    if (self) {
        self.delegate = self;
    }

    return self;
}

//表示手势共存:gestureRecognizer 和 otherGestureRecognizer 是否可以共存 ,返回YES可以
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}


@end

2.如果要使一个手势优先级的优先级大于另一个手势的优先级?( 例如一个View中有scrollView,那么navigationController的popRecognizer和scrollView的手势造成冲突,只会优先响应popRecognizer)

三种解决方法

第一种和第二种类似,即实现UIGestureRecognizer的代理方法

//返回YES gestureRecognizer手势不识别  ,otherGestureRecognizer识别
//返回NO gestureRecognizer手势识别  ,otherGestureRecognizer不识别
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return NO;
}

//返回YES gestureRecognizer手势识别  ,otherGestureRecognizer不识别
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

第三种,所有手势都有一个方法

- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

otherGestureRecognizer的优先级高于当前GestureRecognizer。

案例

该案例结合了事件传递、响应区域、手势冲突等

分析:scrollView的滑动方式是按照pagingEnabled的形式,且scrollView的width是小于屏幕宽度的。而且scrollView是存在多个手势,viewContoller也存在手势,势必会造成手势冲突。


-(void)learnScrollView{

    // 超过view范围的不显示,由于scrollView超过view的返回会显示,所以让其为YES
    self.view.clipsToBounds = YES; 
    
    CustomScrollView * scrollView = [[CustomScrollView alloc] initWithFrame:CGRectMake(20.f, 50.f, self.view.frame.size.width - 60, (self.view.frame.size.width - 80)*0.5)];
    scrollView.contentSize = CGSizeMake((self.view.frame.size.width - 60)*5, (self.view.frame.size.width - 80)*0.5);
    scrollView.clipsToBounds = NO;//超过scrollView范围也能显示
    scrollView.pagingEnabled = YES;
    for (int i = 0; i < 5; i++) {
        UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20 + (self.view.frame.size.width - 60) *i, 0, (self.view.frame.size.width - 80), (self.view.frame.size.width - 80)/2)];
        imageView.image = [UIImage imageNamed:imageArr[i]];
        [scrollView addSubview:imageView];
    }
    [self.view addSubview:scrollView];
    
    //scrollView手势的优先级高于interactivePopGestureRecognizer
    //防止滑动scrollView时退出Controller
    [self.navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail:scrollView.panGestureRecognizer];
}

由于ScrollView的宽度是小于屏幕宽度的所以在滑动边缘的时候是不会成功,所以需要自定义ScrollView修改其点击范围

#import "CustomScrollView.h"

@implementation CustomScrollView

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{

    CGRect frame = self.bounds;
    
    frame.origin.x -= 20;
    frame.size.width = [UIScreen mainScreen].bounds.size.width;
    
    if (CGRectContainsPoint(frame, point)) {
        return YES;
    }
    return [super pointInside:point withEvent:event];
}

@end

demo地址 https://github.com/lijsrn/ScollViewDemo

猜你喜欢

转载自blog.csdn.net/a1034386099/article/details/87157675