获取点击UITableViewCell中的UIButton所在的行

iOS开发中最经常用到的控件就是UITableView,几乎大部分的需求都可以通过UITableView来实现。虽然UITableViewCell有自己的点击方法

1
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

但是我们也经常需要在UITableViewCell中添加一些UIButton来实现需求。因为UITableView会使用复用机制来节省内存的使用,所以如果单纯的给cell中的按钮添加点击事件往往会照成获取行错误的问题。

解决这个问题我们可以使用

1
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;

这个方法进行点击位置坐标的转换,然后通过位置坐标,使用

1
- (nullable NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;

这个方法来获取对应的行。

具体的使用就是这样:

  • cell的创建部分:
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
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = @"myCellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
UILabel *myTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 50)];
myTextLabel.tag = 100;
myTextLabel.textColor = [UIColor blackColor];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.bounds.size.width-100, 0, 100, 50)];
myButton.tag = 200;
[myButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[myButton addTarget:self action:@selector(myButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:myTextLabel];
[cell.contentView addSubview:myButton];
}
//根据tag获取控件
UILabel *myTextLabel = (UILabel *)[cell.contentView viewWithTag:100];
UIButton *myButton = (UIButton *)[cell.contentView viewWithTag:200];
myTextLabel.text = [NSString stringWithFormat:@"这是第%ld行",indexPath.row];
[myButton setTitle:[NSString stringWithFormat:@"%ld行按钮",indexPath.row] forState:UIControlStateNormal];
return cell;
}
  • 点击的响应部分
1
2
3
4
5
6
7
8
9
10
11
12
- (void)myButtonClicked:(UIButton *)sender
{
//获取屏幕上点击按钮位置在tableview中的位置
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.mainTableView];
//根据坐标获取tableview的index
NSIndexPath *indexPath = [self.mainTableView indexPathForRowAtPoint:buttonPosition];
//如果indexPath不为空
if(indexPath)
{
...
}
}

实现的效果:

image


Demo可以在这里下载。