Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get UITableViewCell object from a UIButton action method?

I have a UITableView in which I have added a UIButton as accessory view for each cell. Note that I set the tag of the button as current row for future use.

- (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;
}

Now when one of these buttons is tapped, I need to make changes to the cell. So I implement cellButtonAction where I use the tag to get back the cell:

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

But this seems like a very round about way. Is there a cleaner way to do this?

like image 738
gigahari Avatar asked Mar 21 '26 15:03

gigahari


2 Answers

So assuming that the button is in the contentView directly:

  • ask "sender" (ie the button) for its superview, which is the cell's contentView

  • ask that view for its superView, which is the cell

  • ask the tabview for the index of this cell:

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

EDIT: Actually, I use a general purpose method or function now that just walks up the superviews, looking for a view that is 'KindOf' a UITableViewCell or a UICollectionViewCell. Works like a champ!

The code in 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
}
like image 167
David H Avatar answered Mar 24 '26 09:03

David H


You can do it in a easier way. You will get the table view cell using the sender parameter. Check the following code.

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

Here,

  1. You are casting the sender of type id to a UIButton
  2. You are calling the getter superview of that button, it will give you the UITableViewCell
  3. Doing your customization.
like image 37
Midhun MP Avatar answered Mar 24 '26 09:03

Midhun MP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!