在开发中碰到了下面的问题.由于点击事件比较多,需要添加手势进行添加点击事件.然后出现了手势冲突的问题.尤其是 tap 点击事件与 tableView的点击事件. 开始以为是手势和 View 的添加顺序有影响,后来经测试不是这方面的问题
下面是测试的数据, 一个tableView, 一个 tap 手势,一个 button:
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
[self.view addSubview:tableView];
tableView.delegate = self;
tableView.dataSource = self;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
tap.delegate = self; // 解决问题时设置代理
[self.view addGestureRecognizer:tap];
[tap addTarget:self action:@selector(click)];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 50, 50)];
btn.backgroundColor =[UIColor redColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
cell.textLabel.text = @"aaaa";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"-----");
}
- (void)click {
NSLog(@"=====");
}
- (void)clickBtn {
NSLog(@"aaaa");
}
通过点击方法,有下面的情况:
1> 点击 view 会执行 click 方法;
2> 点击 tableView 只会执行 click 方法 *- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath *不会被执行;
3> 点击 btn, 会执行 clickBtn 方法;
很明显, tableView 和手势有冲突, btn 却没有.
解决方案 控制器遵守协议 UIGestureRecognizerDelegate,实现下面的方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// 点击tableViewCell不执行Touch事件
if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}