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

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

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

相关推荐
开心猴爷6 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
iOS开发上架哦6 小时前
iOS应用耗电测试:使用Energy Log、Keymob和Instruments进行性能监控与能源消耗分析
后端·ios
_瑞8 小时前
APM_KSCrash 原理
ios
あ-12 小时前
mac dbeaver安装后显示数据包损坏
macos
钱栈up12 小时前
从 macOS 切回 Windows,我用 5 个免费工具把 80% 操作习惯搬了回来
windows·macos·策略模式
91440623214 小时前
mac Git 账户切换问题
git·macos
铁锚15 小时前
清理macos系统DS_Store文件的sh脚本
macos
茶底世界之下15 小时前
窗光静物一定要更亮吗?用 Awaking 把曝光收回一点
ios
ii_best17 小时前
ios手机开发安卓脚本开发软件[按键精灵教程]从「找最小值」到「Boss 最近刷新」再到「屏幕范围极值」
android·ios·智能手机·自动化·按键精灵
Hello_Pyhx20 小时前
CrossPaste 跨系统剪贴板配置:按发现、配对、同步逐层排查
macos·电脑