我们在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];
发现拖动列表的时候,无法滚动,只能响应我们自己添加的手势方法,
所以这个方法,是直接调用实例方法,设置两个手势的优先级