场景
我们偶尔候会遇到如许的一个交互场景:我们有一个UITableView
放在一个弹窗中,这个弹窗可以通过滑动举行展示和消散(跟手滑动的方式),然后这个UITableView放在弹窗中,而且可以滚动,展示一些内容,好比商品信息,品评,(雷同抖音的品评弹窗),而且下滑的时间,如果tableView已经滑动到了顶部,就可以相应滑动手势,继承向下滑动弹窗。
思绪
起首,我们弹窗视图中有一个tableView,这个tableView是可以正常的滑动的,然后,我们在弹窗视图中添加一个滑动手势,手势的相应方法中,修改弹窗的frame。以是,这个弹窗视图是要相应手势的署理
方的,而且 在
- (BOOL)gestureRecognizer
UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer UIGestureRecognizer *)otherGestureRecognizer
署理方法中,如果gestureRecognizer 是自身的滑动手势,otherGestureRecognizer是tableView 的滑动手势,则必要支持同时相应的,即返回YES,同时,必要有个主意事项,就是如果我们的
tableView滚动到最顶部了,就必要设置tablView的滚动手势不支持相应,否则的话,就会导致 滚动到顶部的时间,tableView还会继承滚动,如果这个时间往返滑动tableView,就会造成弹窗和tableView 同时滚动的环境,这是我们不想要的,以是我们tablView滚动到顶部的时间,就必要设置tableView的pangesture.enabled = NO.
双滑动手势滚动相应机制
如果我们给tableView的父视图添加一个滑动手势,同时我们在tableView上面滑动,
这时间,如果不支持同时相应,是只有tableView的滑动的,由于默认环境下
:上层的优先相应, 而且同时相应默认是关闭的
而且颠末测试发现,如果我们支持同时相应,则上层视图的gestureRecognizerShouldBegin
先实行,这里就是 tableView 自身滑动手势的gestureRecognizerShouldBegin 先实行,父视图的后实行,这里可以通过自界说一个uitableView的子类来重写gestureRecognizerShouldBegin 方法测试
我们给弹窗添加一个滑动手势,相应方法为handlePan:
通过测试我们发现,我们手在tableView 上滚动的时间,每次实行
tableView 的 署理方法 scrollViewDidScroll 之前,都会实行 handlePan方法。
请看下图
由图可知,手势相应方法是直接出发的,而
scrollViewWillBeginDragging是颠末update之后触发的,以是机会在手势相应方法反面
这里是打印,验证了上面的结论
同样,更新偏移量的方法更是在begindragging 之后了
如图
实行次序
而且,在一次滑动(手没有脱离屏幕算同一次滑动)过程中,
如果相应方法 handlePan 中有设置过
self.tableView.panGestureRecognizer.enabled = NO; 就会导致
本次滑动中self.tableView 不会滚动,即便在self.tableView.panGestureRecognizer.enabled = NO反面设置了 self.tableView.panGestureRecognizer.enabled = YES也不会滚动
这阐明,**在一次滑动手势的相应中, self.tableView.panGestureRecognizer.enabled = NO 的优先级是最高的
以是,使用上面这个特性,我们如果可以在父视图的相应方法中设置tableView的滚动属性- - (void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- NSLog(@"哈哈哈哈哈这里是执行scrollViewDidScroll self.panNum是%ld", self.panNum);
- }
复制代码- - (void)handlePan:(UIPanGestureRecognizer *)pan
- {
- self.tableView.panGestureRecognizer.enabled = YES;
- NSLog(@"哈哈哈哈哈这是第%ld次响应滑动手势handlePan 方法", self.panNum);
- if (self.panNum % 2 == 0) {
- self.tableView.panGestureRecognizer.enabled = NO;
- } else {
- self.tableView.panGestureRecognizer.enabled = YES;
- }
- self.tableView.panGestureRecognizer.enabled = YES;
- }
复制代码
以上测试的完备代码- //// LBPangestureController.m// TEXT//// Created by mac on 2024/7/7.// Copyright © 2024 刘博. All rights reserved.//#import "LBPangestureController.h"@interface LBPangestureController () <UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>@property (nonatomic, strong) UITableView *tableView;@property (nonatomic, strong) UIPanGestureRecognizer *pangesture;@property (nonatomic, assign) NSInteger panNum;@end@implementation LBPangestureController- (void)viewDidLoad { [super viewDidLoad]; [self.view addSubview:self.tableView]; [self.view addGestureRecognizer:self.pangesture]; // Do any additional setup after loading the view.}- (void)handlePan:(UIPanGestureRecognizer *)pan{ self.tableView.panGestureRecognizer.enabled = YES; NSLog(@"哈哈哈哈哈这是第%ld次相应滑动手势handlePan 方法", self.panNum); if (self.panNum % 2 == 0) { self.tableView.panGestureRecognizer.enabled = NO; } else { self.tableView.panGestureRecognizer.enabled = YES; } self.tableView.panGestureRecognizer.enabled = YES;}#pragma mark - UITableViewDelegate, UITableViewDataSource- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class])]; cell.textLabel.text = [NSString stringWithFormat:@"%ld", indexPath.row]; return cell;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 100;}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 60;}#pragma mark - uiscrollViewdelegate- (void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- NSLog(@"哈哈哈哈哈这里是执行scrollViewDidScroll self.panNum是%ld", self.panNum);
- }
- #pragma mark - gesturedelegate- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ if (gestureRecognizer == self.pangesture) { self.panNum ++; } return YES;}- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ if (gestureRecognizer == self.pangesture && otherGestureRecognizer == self.tableView.panGestureRecognizer) { return YES; } return NO;}#pragma mark - lazy load- (UITableView *)tableView{ if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 100, 300, 400) style:UITableViewStylePlain]; [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])]; _tableView.delegate = self; _tableView.dataSource = self; _tableView.backgroundColor = [UIColor cyanColor]; } return _tableView;}- (UIPanGestureRecognizer *)pangesture{ if (!_pangesture) { _pangesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; _pangesture.delegate = self; } return _pangesture;}/*#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller.}*/@end
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |