如何从UIButton操作方法获取UITableViewCell对象?
我有一个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]; }
但这似乎是一个非常圆的方式。 有更清洁的方法吗?
假设该按钮直接位于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 }
你可以更容易地做到这一点。 您将使用sender参数获取表视图单元格。 检查以下代码。
-(void)editCommentButtonAction:(id)sender { UIButton *button = (UIButton *)sender; UITableViewCell *cell = (UITableViewCell*)[button superview]; [self makeChangesToCell:cell]; }
这里,
- 您正在将类型为
id
的sender
强制转换为UIButton
- 您正在调用该按钮的getter
superview
,它将为您提供UITableViewCell
- 进行自定义。
您可以按如下方式获取单元格。
-(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]; }
我有同样的情况,问题是我在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的正确行和部分..只需修改代码。 ;)
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],在某些情况下会失败。
我通常这样做的方式:
- cell存储给定行或索引路径的数据
- 使用方法-didSelectSomething或-didSelectAtIndexPath创建协议:
- 单元格保存对协议实例的引用,该实例将是您的数据源
- 将按钮动作连接到笔尖中的单元格
- 让单元格调用委托
- 请勿忘记在prepareForReuse中清理单元格。 在单元格中存储状态可能会导致令人讨厌的错误,因此请务必在重用时进行清理。
标签是一个真正的黑客,如果你有多个部分它将无法正常工作。 如果您对笔尖中的视图重新排序,发件人superview将会中断。
对于这种特殊情况(附件视图),是不是有专用的表委托方法?