解决UITableViewCell中的元素无法触发点击事件

最近在写自定义UITableViewCell的时候,发现添加到cell里面的一些可点击元素失效,不能够响应点击事件,程序也不出现异常,开始没有想到应对的策略,就想到了手势操作。

方法一:运用IOS中的手势操作

需要在UITableView上面加上手势操作,代码如下:

TestViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

@interface TestViewController () <UITableViewDataSource, UITableViewDelegate>

@end

@implementation TestViewController {
UITableView *contentTableView;
}

- (void)viewDidLoad
{
[super viewDidLoad];
//初始化点击手势
UITapGestureRecognizer *tagGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
tagGesture.numberOfTapsRequired = 1;

contentTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
contentTableView.dataSource = self;
contentTableView.delegate = self;
//给tableView添加手势操作
[contentTableView addGestureRecognizer:tagGesture];
}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 50, 30)];
label.tag = 1;
[cell.contentView addSubview:label];
}

UILabel *label = (UILabel *)[cell.contentView viewWithTag:1];
label.text = [NSString stringWithFormat:@"text_%d", indexPath.row];
return cell;
}

#pragma mark - UITableViewDelegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100.0f;
}

#pragma mark - UITapGestureRecognizer

- (void)tapGesture:(UITapGestureRecognizer *)gesture {

//获得当前手势触发的在UITableView中的坐标
CGPoint location = [gesture locationInView:contentTableView];
//获得当前坐标对应的indexPath
NSIndexPath *indexPath = [contentTableView indexPathForRowAtPoint:location];

if (indexPath) {
//通过indexpath获得对应的Cell
UITableViewCell *cell = [contentTableView cellForRowAtIndexPath:indexPath];
//获得添加到cell.contentView中的UILabel
UILabel *label = nil;
for (UIView *view in cell.contentView.subviews) {
if ([view isKindOfClass:[UILabel class]]) {
label = (UILabel *)view;
break;
}
}

//获得当前手势点击在UILabe中的坐标
CGPoint p = [gesture locationInView:label];
//看看手势点的坐标是不是在UILabel中
if (CGRectContainsPoint(label.frame, p)) {
NSLog(@"label text : %@", label.text);
}
}

}

今天重新看代码,想想能不能找到一个更加简单的方法,因为添加在cell.contentView中的UIButton,有些是可以点击,有些却不可以点击,这让人作势的郁闷啊,所以,我就打印看看cell.contentView.size,居然打印出来的结果是(320, 44),原来保持了默认的大小,所以如果你的button在这个默认的大小范围内,就可以点击,如果超出了这个大小的范围就不能够响应事件了,而我的自定义的UITableViewCell的高度为100,所以需要自己设定cell.contentView的大小,这样就不需要添加复杂的手势操作了。

方法二:自定义cell.contentView的大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(100, 20, 50, 30);
[btn setTitle:@"测试" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
//神奇的设置
cell.contentView.frame = CGRectMake(0, 0, tableView.width, [self tableView:tableView heightForRowAtIndexPath:indexPath]);
[cell.contentView addSubview:btn];
}
return cell;
}

- (void)btnClick:(UIButton *)btn {
NSLog(@"测试成功");
}

PS:你也可以看看下面两篇StackOver上面问题,当然我也小小的解决了一下,内容和上述文章差不多

Event not triggered for UIButton in UIView in UITableViewCell

Why the UIButton in UITableViewCell.contentView won’t work?

文章目录
  1. 1. 方法一:运用IOS中的手势操作
  2. 2. 方法二:自定义cell.contentView的大小
,