我们在iOS的手势代理方法中看到这样三个方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
其中,前面两个都是手势的代理方法,
后面那个是手势的一个实例方法
那么这三个方法分别是什么作用呢,从字面上看并且从
苹果官方的文档上看, a shouldBeRequiredToFailByGestureRecognizer:b
的含义是手势a (设置代理对象的手势) 的响应 需要
手势b(其他手势)响应失败,就是只有手势b 不相应的时候,手势a才能响应
我们通过如下代码进行测试
shouldBeRequiredToFailByGestureRecognizer
//
// LBGestureFailureController.m
// TEXT
//
// Created by mac on 2025/1/11.
// Copyright © 2025 刘博. All rights reserved.
//#import "LBGestureFailureController.h"@interface LBGestureFailureController () <UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>@property (nonatomic, strong) UITableView *tableView;@end@implementation LBGestureFailureController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor whiteColor];[self.view addSubview:self.tableView];UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan)];pan.delegate = self;[self.view addGestureRecognizer:pan];// Do any additional setup after loading the view.
}- (void)pan
{NSLog(@"相应自己添加的滑动手势");
}#pragma mark - UIGestureRecognizerDelegate- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{return YES;
}- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{return YES;
}#pragma mark - UITableViewDelegate, UITableViewDataSource- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class])];NSString *title = [NSString stringWithFormat:@"%ld", indexPath.row];cell.textLabel.text = title;cell.contentView.backgroundColor = [UIColor cyanColor];return cell;
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{return 60;
}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return 100;
}#pragma mark - lazy load- (UITableView *)tableView
{if (!_tableView) {_tableView = [[UITableView alloc] initWithFrame:CGRectMake(10, 80, 300, 600) style:UITableViewStylePlain];[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];_tableView.delegate = self;_tableView.dataSource = self;_tableView.backgroundColor = [UIColor cyanColor];}return _tableView;
}@end
效果如下
我们滑动列表的时候,只能滚动列表,我们自己添加的滑动手势的方法是没有响应的。
这个时候,我们去掉这句
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
然后在滑动列表,发现我们自己添加的手势方法是有
响应的
因为这句 shouldRequireFailureOfGestureRecognizer
返回YES的时候,就是我们自己添加的手势,需要其他的手势失败的时候,才能响应,就是别的手势要比我们自己添加的手势的级别要高,所以这个时候,只响应了tableView自带的滑动手势
shouldBeRequiredToFailByGestureRecognizer
从字面上看,这个代理方法的意思是其他方法的响应需要我们这个方法响应失败,就是如果我们这个方法响应了,其他方法就不能响应了
如果我们实现了这个方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{return YES;
}
我们发现我们尝试拖动列表的时候,已经无法滚动了,
只响应了我们自己添加的手势的响应方法,因为
其他手势的响应需要我们这个手势失败,但是我们的手势是能响应的,所以列表自带的滑动手势就不能响应了
requireGestureRecognizerToFail
[a requireGestureRecognizerToFail:b], a手势的成功响应需要b手势响应失败,即b 手势的优先级高,
我们添加这句代码
[self.tableView.panGestureRecognizer requireGestureRecognizerToFail:pan];
发现拖动列表的时候,无法滚动,只能响应我们自己添加的手势方法,
所以这个方法,是直接调用实例方法,设置两个手势的优先级