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

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

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

相关推荐
stars2 分钟前
mac homebrew配置使用
macos
白豆五7 分钟前
Homebrew 【MAC安装软件利器】
macos
@逆风微笑代码狗1 小时前
144.《在 macOS 上安装 Redis》
数据库·redis·macos
刘小哈哈哈2 小时前
iOS layer.mask 的原理
ios
安和昂3 小时前
Effective Objective-C 第一章阅读笔记
笔记·ios·objective-c
文件夹__iOS5 小时前
Xcode 正则表达式实现查找替换
macos·正则表达式·xcode
御承扬7 小时前
Hypium UIViewer 让 MacOS 与鸿蒙NEXT手机实现多屏协同
macos·智能手机·harmonyos·多屏协同
omegayy13 小时前
清理Mac硬盘超大占用:.Spotlight-V100
macos
夫琅禾费米线13 小时前
mac使用 —— win转mac的记录
macos