如何从UIButton操作方法获取UITableViewCell对象?

时间:2012-07-26 12:47:18

标签: ios uitableview uibutton

我有一个UITableView,我在其中添加了一个UIButton作为每个单元格的附件视图。请注意,我将按钮的标记设置为当前行以供将来使用。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...

    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

        cellButton = [UIButton buttonWithType:UIButtonTypeCustom];
        cellButton.frame = CGRectMake(0, 0, 30, 30);  

        [cellButton setBackgroundImage:[UIImage imageNamed:@"cellButton.png"] forState:UIControlStateNormal];        
        [cellButton addTarget:self action:@selector(cellButtonAction:) forControlEvents:UIControlEventTouchUpInside];


        cellButton.tag = indexPath.row;  // <= Will use this in the next method
        cell.accessoryView = cellButton;
    }


    //Load cell with row based data

    return cell;
}

现在当点击其中一个按钮时,我需要对单元格进行更改。所以我实现了cellButtonAction,我使用标签来取回单元格:

-(void)editCommentButtonAction:(id)sender
{
    UIButton *button = sender;
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:button.tag inSection:0];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    [self makeChangesToCell:cell];  
}

但这似乎是一种非常圆润的方式。有更清洁的方法吗?

6 个答案:

答案 0 :(得分:5)

假设按钮直接位于contentView

  • 询问“sender”(即按钮)的超级视图,即单元格的contentView

  • 询问该superView的视图,即单元格

  • 向tabview询问此单元格的索引:

- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell

编辑:实际上,我现在使用通用方法或函数,只是走向超级视图,寻找一个'KindOf'是UITableViewCell或UICollectionViewCell的视图。像冠军一样工作!

Swift中的代码:

func containingUITableViewCell(tableView: UITableView, var view: UIView) -> (UITableViewCell, NSIndexPath)? {
while let v = view.superview {
    view = v
    if view.isKindOfClass(UITableViewCell.self) {
        if let cell = view as? UITableViewCell, let indexPath = tableView.indexPathForCell(cell) {
            return (cell, indexPath)
        } else {
            return nil
        }
    }
}
return nil

}

func containingUICollectionViewCell(collectionView: UICollectionView, var view: UIView) -> (UICollectionViewCell, NSIndexPath)? {
    while let v = view.superview {
        view = v
        if view.isKindOfClass(UICollectionViewCell.self) {
            if let cell = view as? UICollectionViewCell, let indexPath = collectionView.indexPathForCell(cell) {
                return (cell, indexPath)
            } else {
                return nil
            }
        }
    }
    return nil
}

答案 1 :(得分:2)

您可以更轻松地完成此操作。您将使用sender参数获取表视图单元格。 请检查以下代码。

-(void)editCommentButtonAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    UITableViewCell *cell = (UITableViewCell*)[button superview];
    [self makeChangesToCell:cell];  
}

下面,

  1. 您正在将sender类型id投射到UIButton
  2. 您正在调用按钮的getter superview,它会为您提供UITableViewCell
  3. 进行自定义。

答案 2 :(得分:2)

您可以按如下方式获取单元格。

    -(void)editCommentButtonAction:(id)sender
    {
        NSIndexPath* indexPath = 0;

        //Convert the bounds origin (0,0) to the tableView coordinate system
        CGPoint localPoint = [self.tableView convertPoint:CGPointZero fromView:sender];

        //Use the point to get the indexPath from the tableView itself.
        indexPath = [self.tableView indexPathForRowAtPoint:localPoint];
        //Here is the indexPath
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        [self makeChangesToCell:cell];  
    }

答案 3 :(得分:1)

我有同样的情况,问题是我在tablecells里面有一个imageView,我想得到一个包含我点击的imageview的单元格。

//MyCell is subclass of UITableViewCell

    if ([[[[sender view] superview] superview] isKindOfClass:[MyCell class]]) {
        MyCell *cell = (MyCell *)[[[sender view] superview] superview];
        NSIndexPath *cellIndexPath = [myTable indexPathForCell:cell];
        NSLog(@"cellIndexPath: %@  - %@",cellIndexPath, [videoURLArray objectAtIndex:cellIndexPath.row]);

    }
  • [发件人视图] - imageView
  • [[发送者视图] superview] - 放置了我的imageView(在这种情况下,我的imageView的superview是单元格的contentView)
  • [[[发送者视图] superview] superview] ---放置了contentView的位置 - 单元格

NSLog部分应该打印已点击的imageView的正确行和部分。只需修改代码即可。 ;)

答案 4 :(得分:1)

Hello gigahari Use the following code.  

- (void)cellStopDownloadButtonClicked:(id)sender 
{
id viewType = [sender superview];
do {
viewType = [viewType superview];
}
while (![viewType isKindOfClass:[CustomCell class]] || !viewType);
CustomCell *cell = (CustomCell *)viewType;
// use the cell
}

这适用于所有情况,例如ios 6和ios 7.在ios 7中,在单元格(内容视图)中添加了额外的视图。

如果使用[[sender superview] superview],在某些情况下会失败。

答案 5 :(得分:0)

我通常这样做的方式:

  • 单元格存储给定行或索引路径的数据
  • 使用方法-didSelectSomething或-didSelectAtIndexPath创建协议:
  • 单元格保存对协议实例的引用,该实例将是您的数据源
  • 将按钮操作连接到笔尖中的单元格
  • 让单元格调用委托
  • 请勿忘记在prepareForReuse中清理单元格。在单元格中存储状态可能会导致令人讨厌的错误,因此请务必在重用时进行清理。

标签是一个真正的黑客,如果你有多个部分它将无法正常工作。 如果您对笔尖中的视图重新排序,发件人superview将会中断。

对于这种特殊情况(附件视图),是不是有专用的表委托方法?