【发布时间】:2011-11-22 04:42:35
【问题描述】:
我有一个显示一行单元格的 tableview 控制器。每个单元格有 3 个按钮。我已将每个单元格的标签编号为 1、2、3。问题是我不知道如何找到按下按钮的单元格。我目前仅在按下其中一个按钮时才获得发件人的标签。有没有办法在按下按钮时获取单元格行号?
【问题讨论】:
标签: objective-c ios uitableview
我有一个显示一行单元格的 tableview 控制器。每个单元格有 3 个按钮。我已将每个单元格的标签编号为 1、2、3。问题是我不知道如何找到按下按钮的单元格。我目前仅在按下其中一个按钮时才获得发件人的标签。有没有办法在按下按钮时获取单元格行号?
【问题讨论】:
标签: objective-c ios uitableview
迅速:
@IBAction func buttonAction(_ sender: UIButton) {
guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
return
}
// do something
}
【讨论】:
你真的应该改用这个方法:
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 决定更改视图结构,所有其他答案都可能会中断。
【讨论】:
convertPoint:*to*View 而不是convertPoint:*from*View。我使用 Xcode 自动完成并最终使用 fromView 方法导致无法正常工作......
斯威夫特 3
注意:这确实应该放在上面的accepted answer 中,除了meta frowns 进行此类编辑。
@IBAction func doSomething(_ sender: UIButton) {
let buttonPosition = sender.convert(CGPoint(), to: tableView)
let index = tableView.indexPathForRow(at: buttonPosition)
}
两个小cmets:
【讨论】:
我想快速分享代码 -
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
}
}
【讨论】:
另一种简单的方法:
在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
// ...
}
【讨论】:
我会推荐这种方式来获取具有任何自定义子视图的单元格的 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。
另外,请注意注释代码,如果您希望通过添加到自定义子视图的 UIGestureRecognizer 的@selector 来获得相同的注释代码。
【讨论】:
编辑:此答案已过时。 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;
【讨论】:
contentView 属性 - 所以这个解决方案并不真正起作用。
有两种方式:
@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);
}
【讨论】:
一种解决方案可能是检查按钮的超级视图的标签,或者在视图层次结构中检查更高的标签(如果按钮在单元格的内容视图中)。
【讨论】:
我假设您在cellForRowAtIndexPath 的单元格中添加按钮,那么我要做的是创建一个自定义类子类UIButton,添加一个名为rowNumber 的标签,并附加该数据在向单元格添加按钮时。
【讨论】:
UIButton 的子类。 tag 是 UIView 的公共属性。