最近被问到一个功能,就是类似美团选择商品界面,从提交订单按钮上往上滑动,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链接了,放个效果图在最后。