我有一个表格视图,每个单元格都有一个按钮附件视图。该表由一个获取结果控制器管理,并经常重新排序。我想能够按下其中一个按钮并获得该按钮的表格视图单元格的索引路径。我一直在尝试存储按钮的行号,但当表格被重新排序时,行号会变得不正确,并且我一直无法正确地重新排序标记。有没有新的想法来跟踪按钮的单元格的索引路径?
我有一个表格视图,每个单元格都有一个按钮附件视图。该表由一个获取结果控制器管理,并经常重新排序。我想能够按下其中一个按钮并获得该按钮的表格视图单元格的索引路径。我一直在尝试存储按钮的行号,但当表格被重新排序时,行号会变得不正确,并且我一直无法正确地重新排序标记。有没有新的想法来跟踪按钮的单元格的索引路径?
如果你不舒服依赖于button.superview
,那么这个方法应该比其他答案更稳健:
UIButton *button = (UIButton *)sender;
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin];
这在iOS 7上不再适用; 可以查看Mike Weller的答案
- (IBAction)clickedButton:(id)sender {
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview;
UITableView *tableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}
更短的写法:
- (IBAction)clickedButton:(id)sender {
NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview];
}
两者都未经测试!
.superviews
来获取 UITableViewCell
的逻辑是:单元格是 accessoryView
的 superview
,而 accessoryView
又是 UIButton
的 superview
。不过我想我错了。 - Douwe MaanUITableViewCell
的视图结构发生更改,您的应用程序会瘫痪。而这在过去曾经发生过。按钮及其处理程序应存在于自定义单元格子类中。这个单元格类可以提供委托或块回调接口,以便您的视图控制器可以通过这种方式钩入按钮事件,并完全访问相应的上下文。 - Mike WellerUITableViewWrapperView
而不是tableView本身。 - memmons使用.superview
来遍历视图层次结构(就像所有现有答案所展示的那样)是一种非常糟糕的做法。如果UITableViewCell
的结构发生变化(这曾经发生过),您的应用程序将会崩溃。在您的代码中看到.superview.superview
应该引起警觉。
按钮及其处理程序应添加到自定义的UITableViewCell
子类中,并在那里进行布局。那是它所属的地方。
然后,该单元格子类可以通过标准委托界面或块委托出按钮事件。您应该朝着这样的目标努力:
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = ...;
// ...
cell.onButtonTapped = ^{
[self buttonSelectedAtIndexPath:indexPath];
}
// OR
cell.delegate = self;
// ...
}
(Note: 如果你选择使用 block,你需要使用 __weak
self 引用来防止保留环路,但我认为这会让示例显得杂乱无序)。- (void)cellButtonPressed:(UITableViewCell *)cell
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// ...
}
当处理事件时,您的代码现在可以完全访问适当的上下文。
在您的单元格类上实现此接口应该很简单。
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
UITableView *curTableView = (UITableView *)cell.superview;
NSIndexPath *indexPath = [curTableView indexPathForCell:cell];
我也遇到了同样的问题,我构建了一个简单的递归方法,无论你触发控件有多深,它都可以正常工作。
-(NSIndexPath*)GetIndexPathFromSender:(id)sender{
if(!sender) { return nil; }
if([sender isKindOfClass:[UITableViewCell class]])
{
UITableViewCell *cell = sender;
return [self.tableView indexPathForCell:cell];
}
return [self GetIndexPathFromSender:((UIView*)[sender superview])];
}
-(void)ButtonClicked:(id)sender{
NSIndexPath *indexPath = [self GetIndexPathFromSender:sender];
}
if(!sender) { return nil; }
- wxactly我创建了一个用于获取indexPath的方法,希望这对你有所帮助。
在cellForRowAtIndexPath中创建按钮操作(aMethod:)
-(void) aMethod:(UIButton *)sender
{
// Calling Magic Method which will return us indexPath.
NSIndexPath *indexPath = [self getButtonIndexPath:sender];
NSLog(@"IndexPath: %li", indexPath.row);
NSLog(@"IndexRow: %li", indexPath.section);
}
// 这是获取按钮indexPath的神奇方法
-(NSIndexPath *) getButtonIndexPath:(UIButton *) button
{
CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable];
return [groupTable indexPathForRowAtPoint:buttonFrame.origin];
}
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(@"%@",indexPath);
SWIFT 2 更新
以下是如何查找点击的按钮的方法
@IBAction func yourButton(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
print("Tap tap tap tap")
}