iOS手势shouldBeRequiredToFailByGestureRecognizer 机制

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

相关推荐
WuYiCheng6665 小时前
TLS 1.3黑魔法:从协议破解到极致性能调优
macos
piaoxue8207 小时前
Mac上安装运行SynthTIGER
macos·语言模型
小山菌8 小时前
mac中加载C++动态库文件
开发语言·c++·macos
THMAIL9 小时前
mac M芯片运行docker-desktop异常问题
macos·docker·容器
laocooon52385788615 小时前
一台入网的电脑有6要素, 机器名,mac,ip,俺码,网关,dns,分别有什么作用
网络协议·tcp/ip·macos
若水无华1 天前
fiddler 配置ios手机代理调试
ios·智能手机·fiddler
Aress"1 天前
【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
ios·uni-app·ipa安装
德亦周1 天前
如何在Mac电脑上的VScode去配置C/C++环境
c++·vscode·macos
tonngw1 天前
【Mac 从 0 到 1 保姆级配置教程 12】- 安装配置万能的编辑器 VSCode 以及常用插件
git·vscode·后端·macos·开源·编辑器·github
亚林瓜子1 天前
虚拟Python 环境构建器virtualenv安装(macOS版)
python·macos·virtualenv·pipx