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

相关推荐
博观而约取11 小时前
Linux 和 macOS 终端中常见的快捷键操作
linux·运维·macos
Alger_Hamlet12 小时前
Photoshop 2025 Mac中文 Ps图像编辑软件
macos·ui·photoshop
资源大全免费分享12 小时前
MacOS 的 AI Agent 新星,本地沙盒驱动,解锁 macOS 操作新体验!
人工智能·macos·策略模式
鸿蒙布道师13 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
刘小哈哈哈14 小时前
封装了一个iOS多分区自适应宽度layout
macos·ios·cocoa
YJlio17 小时前
TrollStore(巨魔商店)介绍及操作手册
macos·objective-c·cocoa
mywpython18 小时前
mac 最新的chrome版本配置selenium的方式
chrome·python·selenium·macos
布多19 小时前
Tagged Pointer:苹果工程师的内存优化艺术
ios·源码
Rudon滨海渔村20 小时前
新旧iPhone相册复制 - 相册图片视频对拷 - 换机 - 迁移设备数据 - 免费开源爱思助手
ios·iphone
一道微光20 小时前
mac air m系列arm架构芯片安装虚拟机 UTM+debian 浏览器firefox和chrome
arm开发·macos·架构