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];

发现拖动列表的时候,无法滚动,只能响应我们自己添加的手势方法,

所以这个方法,是直接调用实例方法,设置两个手势的优先级

相关推荐
高调的涵涵2 小时前
1GB 文件,df 说没占地方
macos
茶底世界之下9 小时前
窗边白雏菊与旧书:用 Awaking 留住一束暖光
ios·app·产品
奶油话梅糖10 小时前
苹果的内核跑上了安卓手机:2,631 Star 的 HakiOS 让 XNU 在 Adreno GPU 上画出 118 帧
android·macos·智能手机
独隅1 天前
WebStorm macOS 安装调优与实战效果全景
ide·macos·webstorm
茶底世界之下1 天前
阴天海边的蓝船:用 Awaking 把灰蓝调成清亮主角
ios·app·产品
木子欢儿1 天前
国内 macOS/Linux 安装 rust
linux·运维·服务器·macos·rust
Digitally1 天前
如何将 iPhone 备份到 iCloud?
ios
传奇开心果编程2 天前
【Flutter踩坑排雷】第19课:路由硬编码坑|字符串路由书写错误,页面跳转失败排查
android·flutter·ios·移动开发·跨平台·ui框架·声明式ui
茶底世界之下2 天前
雨后街口的斑马线:用 Awaking 把颜色让给光与步伐
ios·app·产品
一个人旅程~3 天前
关于imac27inch因改短用户名导致混合硬盘和系统崩溃的问题分析与故障解决
经验分享·笔记·macos·新浪微博