我有一个显示一行单元格的tableview控制器。每个单元格有3个按钮。我已将每个单元格的标签编号为1,2,3。问题是我不知道如何找到按下按钮的单元格。我当前只在按下其中一个按钮时才收到发件人的标签。当按下按钮时,有没有办法获取单元格行号?
答案 0 :(得分:278)
你应该真的使用这种方法:
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
Swift版本:
let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)
根据按下的按钮的位置,这将给你indexPath
。如果您需要单元格,则只需拨打cellForRowAtIndexPath
,或者如果需要行号,则拨打indexPath.row
。
如果您是偏执狂,可以在使用之前检查if (indexPath) ...
,以防万一在表格视图中找不到indexPath
。
如果Apple决定更改视图结构,所有其他答案都可能会中断。
答案 1 :(得分:40)
编辑:这个答案已经过时了。 Please use this method instead
试试这个:
-(void)button1Tapped:(id)sender
{
UIButton *senderButton = (UIButton *)sender;
UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
UITableView* table = (UITableView *)[buttonCell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
NSInteger rowOfTheCell = [pathOfTheCell row];
NSLog(@"rowofthecell %d", rowOfTheCell);
}
编辑:如果您使用的是contentView,请将其用于buttonCell:
UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;
答案 2 :(得分:17)
我建议这种方式来获取具有任何自定义子视图的单元格的indexPath - (与iOS 7兼容以及所有以前的版本)
-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
// UIView *parentCell = gestureRecognizer.view.superview;
UIView *parentCell = sender.superview;
while (![parentCell isKindOfClass:[UITableViewCell class]]) { // iOS 7 onwards the table cell hierachy has changed.
parentCell = parentCell.superview;
}
UIView *parentView = parentCell.superview;
while (![parentView isKindOfClass:[UITableView class]]) { // iOS 7 onwards the table cell hierachy has changed.
parentView = parentView.superview;
}
UITableView *tableView = (UITableView *)parentView;
NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];
NSLog(@"indexPath = %@", indexPath);
}
这也不需要self.tablview
。
另外,请注意注释代码,如果您希望通过添加到自定义子视图中的@selector UIGestureRecognizer来使用相同的代码。
答案 3 :(得分:3)
有两种方法:
@ H2CO3是对的。您可以执行@ user523234建议的操作,但只需稍加更改即可遵守应该位于UIButton和UITableViewCell之间的UITableViewCellContentView。所以要修改他的代码:
- (IBAction)button1Tapped:(id)sender
{
UIButton *senderButton = (UIButton *)sender;
UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview;
UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview;
UITableView* tableView = (UITableView *)tableViewCell.superview;
NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell];
NSInteger rowOfTheCell = pathOfTheCell.row;
NSLog(@"rowofthecell %d", rowOfTheCell);
}
如果您创建自定义UITableViewCell(您自己的子类),那么您只需在IBAction中调用self
即可。您可以使用故事板或在设置单元格时以编程方式将IBAction功能链接到按钮。
- (IBAction)button1Tapped:(id)sender
{
UITableView* tableView = (UITableView *)self.superview;
NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
NSInteger rowOfTheCell = pathOfTheCell.row;
NSLog(@"rowofthecell %d", rowOfTheCell);
}
答案 4 :(得分:2)
我假设您在cellForRowAtIndexPath
中向单元格添加按钮,然后我要做的是创建自定义类子类UIButton
,添加名为{{1}的标记在向单元格添加按钮时附加该数据。
答案 5 :(得分:2)
另一种简单的方法:
获取tableView
然后在点
索引路径包含行索引
代码是:
- (void)buttonTapped:(id)sender {
UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
CGPoint point = [tap locationInView:theTableView];
NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];
NSInteger theRowIndex = theIndexPath.row;
// do your stuff here
// ...
}
答案 6 :(得分:1)
Swift 3
注意:这应该在accepted answer以上,除了meta frowns进行此类修改。
@IBAction func doSomething(_ sender: UIButton) {
let buttonPosition = sender.convert(CGPoint(), to: tableView)
let index = tableView.indexPathForRow(at: buttonPosition)
}
两条小评论:
答案 7 :(得分:0)
一种解决方案可能是检查按钮的超级视图的标记,或者在视图层次结构中检查更高的标记(如果按钮位于单元格的内容视图中)。
答案 8 :(得分:0)
我想在swift中共享代码 -
extension UITableView
{
func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
{
var view = view1;
while view != nil {
if (view?.isKindOfClass(UITableViewCell) == true)
{
return self.indexPathForCell(view as! UITableViewCell)!
}
else
{
view = view?.superview;
}
}
return nil
}
}
答案 9 :(得分:0)
在swift:
@IBAction func buttonAction(_ sender: UIButton) {
guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
return
}
// do something
}