最近被问到一个功能,就是类似美团选择商品界面,从提交订单按钮上往上滑动,tableView可以响应,向上滑动,点击按钮,按钮不受影响,不明白的小伙伴可以打开美团看看,从按钮上往上滑,tableView可以响应。
一开始的思路是利用的button的addTarget方法,dragOut时给tableView一个向上的偏移量,但是滑动太过僵硬,不是很友好,最后想到通过手势传递hitTest来处理,但是这里的场景还多了一个按钮,最后也被放弃,最后的最后,想到按钮和点击区域,遂解决这个问题。
思路:按钮关闭交互,且层级高于tableView,让他们都以self.view为superView,给tableView设置和按钮一样宽高的tableFooterView,这样按钮即不会挡住tableView内容,而且按钮关闭交互后滑动时,tableView就可以响应了,接下来是点击区域的设置,将点击手势增加到self.view上,设置点击的有效范围为按钮的区域:
详细可看如下代码:
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate> { UITableView *tableView; UIButton *btn; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor whiteColor]; tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) style:UITableViewStylePlain]; tableView.delegate = self; tableView.dataSource = self; [self.view addSubview:tableView]; tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)]; btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.userInteractionEnabled = NO; btn.frame = CGRectMake(0, self.view.bounds.size.height - 50, self.view.bounds.size.width, 50); [btn setTitle:@"Centain" forState:UIControlStateNormal]; [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; btn.backgroundColor = [UIColor orangeColor]; [self.view addSubview:btn]; UITapGestureRecognizer *ges = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(btnAction:)]; ges.delegate = self; [self.view addGestureRecognizer:ges]; } #pragma mark - btnAction - (void)btnAction:(UITapGestureRecognizer *)ges { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"点击按钮" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; } - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { CGPoint point = [gestureRecognizer locationInView:self.view]; if (point.y < self.view.bounds.size.height - 50) { return NO; } return YES; } #pragma mark - UITableViewDelegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 30; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 50; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } cell.textLabel.text = [NSString stringWithFormat:@"This is the row at index %ld!!!", indexPath.row]; return cell; }
代码比较简单,就不放git链接了,放个效果图在最后。