【问题标题】:How do you get the indexPath of the cell you are tapping?你如何获得你正在点击的单元格的 indexPath?
【发布时间】:2014-12-30 21:24:48
【问题描述】:

当在 UITableView 中的单元格上执行长按时,我正在尝试执行 IBAction。该操作涉及单元格的内容,因此我需要获取 indexPath 以便从本地存储中的字典中检索内容。 IBAction 方法在包含 UITableView 方法的 MasterViewController.m 文件中定义,并且是 UITableViewController 的子类。我已经尝试了以下所有方法,它们都返回 null 而不是单元格的 indexPath。

UITableViewCell *cell = (UITableViewCell *)self;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];

我还看到了几年前使用视图中单元格位置的类似问题的答案,但我也无法让其中任何一个工作。

更新: IBAction、sendToPB 是在 UITableViewController 的子类中定义的。 Interface Builder 的单元格中添加了一个长按手势识别器,Sent Actions 连接到 sendToPB。当您长按表格视图中的单元格时,该操作应该是将单元格的内容复制到剪贴板。到目前为止,我尝试过的所有方法都为 indexPath 返回 null。

- (IBAction)sendToPB:(id)sender {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    NSString *object = self.objects[indexPath.row];
    UIPasteboard *pb = [UIPasteboard generalPasteboard];
    NSString *pressedCellText = [[Data getAllNotes] objectForKey:object];
    [pb setString: pressedCellText];
}

更新: 我发现这种方法有两个问题。首先,长按手势实际上并没有选择行,这就是所有使用indexPathForSelectedRow 的选项都不起作用的原因。其次,sender 是手势识别器,而不是单元格或行,因此使用sender 也会为indexPath 生成一个空值。考虑到这两个因素,您还能如何检测您在哪个单元格上执行了长按?

【问题讨论】:

  • 调试的时候,self看起来是什么类型的对象?您将其转换为表格单元格,但随后您也调用 self.tableView ,就像它是视图控制器一样。
  • 添加代码 sn-p 用于将长手势添加到单元格
  • 您需要显示更多代码。展示如何设置和处理长按。
  • 请看下面我的回答,试试 NSIndexPath *indexPath = self.tableview.indexPathForSelectedRow 然后断点,报告indexPath和object的值。
  • @ChiliOcean 不,它可能使手势识别器成为发送者。为什么不使用调试器进行检查。

标签: ios uitableview ibaction nsindexpath


【解决方案1】:

你可以在 longPressGesture 上像这样获得 indexPath!

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
     CGPoint p = [gestureRecognizer locationInView:self.myTableView];

     NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:p];
     if (indexPath == nil) {
         NSLog(@"long press on table view but not on a row");
     } 
     else if (gestureRecognizer.state == UIGestureRecognizerStateBegan) 
     {

         NSLog(@"long press on table view at row %d", indexPath.row);
     } 
     else 
     {
         NSLog(@"gestureRecognizer.state = %d", gestureRecognizer.state);
     }
}

也许这个链接会对你有所帮助more

【讨论】:

  • 不要只是从另一个答案中复制一个块。这充其量只是一条评论。
  • 是的,但我也把那个链接放在我复制的地方,用户只需要 indexpath 所以我复制了它!
【解决方案2】:

将 .h 文件中的变量 1st 声明为

 NSIndexPath *hitIndex;

然后通过长按方法,您可以获得单元格的位置,从而获得索引路径

(void)longPressMethod:(UIButton *)btn
{

CGPoint hitPoint = [btn convertPoint:CGPointZero toView:tbl_traits];
hitIndex = [tbl_traits indexPathForRowAtPoint:hitPoint];

}

【讨论】:

  • 什么是tbl_traits?为什么hitIndex 需要一个 ivar?你指的是哪个 .h 文件?
  • tbl_trait 是 tableview 的对象 & hitIndex 是 NSIndexPath 对象,这样你就可以使用 hitIndex.row 获取单元格的内容 & .h 是简单的控制器 .h 文件来声明变量。
  • OP 的问题中哪里提到了tbl_traits 和“简单控制器”?您的回答令人困惑且断章取义。
  • simple controller 只是你添加 tableview 的控制器 & tbl_trait 是 tableview 的对象,长按手势方法将在那里,你可以添加这个方法如下:UILongPressGestureRecognizer *lpgr = [[ UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMethod:)]; lpgr.minimumPressDuration = 2.0; //秒 lpgr.delegate = self; [自己。 tbl_traits addGestureRecognizer:lpgr]; [lpgr 发布];
【解决方案3】:

您可以使用手势识别器来做到这一点。希望这些sn-ps对您有所帮助.......

在你的.h file

@interface yourClass ()
{
    UILongPressGestureRecognizer *longPressRecognizer;
}

在 viewDidLoad 中,

longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDetected:)];
longPressRecognizer.minimumPressDuration = 2;
longPressRecognizer.numberOfTouchesRequired = 1;
longPressRecognizer.delegate = self;

在 cellForRowAtIndexPath 中,就在 return 语句之前

[cell addGestureRecognizer:longPressRecognizer];

最后,

- (void) longPressDetected:(UILongPressGestureRecognizer *)recognizer 
{
    UITableViewCell *selectedCell = (UITableViewCell *)recognizer.view;
    // Your required code here
}

【讨论】:

  • 在您正在回答的同一个问题上投反对票是非常不道德的。它表明您这样做是为了宣传您的答案。该 QA 的 OP 或其他查看者应该赞成或反对。
  • 好的,如果是这样,我很抱歉。我对SO相当陌生。您能否为我提供一个适当的规则链接等?我收回我的反对票。
  • 没有汗水。有一天我们都是新的!
  • 谢谢!不过,任何指向规则或指南的链接都会很有帮助。
  • 你没有做错任何事,元堆栈溢出是了解规则等的最佳场所。
【解决方案4】:

编辑:感谢@RegularExpression

首先一定要设置你的tableView的委托

self.myTableView.delegate = self

我相信这就是您正在寻找的:

斯威夫特

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    //save the indexPath.row as an integer inside a property or pass it to your action
}

然后,您可以保存上述方法的索引,或者简单地调用您的操作,在上述方法中传递该索引。

目标-C

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

       //save the indexPath.row as an integer inside a property or pass it to your action
}

【讨论】:

  • 但请确保您已设置好委托。
  • 如果您试图确定是否在没有内部修饰的情况下发生了长按,我认为这不起作用。
【解决方案5】:

如果这是在 UITableViewController 子类中,则将 self(它是 UITableViewController 子类的一个实例)转换为 UITableViewCell 将不会返回所选单元格。

实际上有两种方法:

1- 简单的方法:不要使用 IBAction,只实现委托方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

2- 相对简单的方法:在你的 IBaction 中,你可以通过属性获取选中的单元格:

self.tableview.indexPathForSelectedRow

此属性将为您提供所选单元格的索引路径。

【讨论】:

  • 用户想要检测长按。对不起老兄,这个是-1。
  • @LibranCoder 我认为您对投票的规则感到困惑。我建议你审查他们。 OP 的问题是如何确定被选中的单元格,而不是如何创建长按手势识别器。
  • 很抱歉造成误会。
  • @librancoder 是对的,问题是关于检测哪个单元格被长按,而不是哪个单元格被选中。并且对您正在回答的问题的其他答案投反对票并没有错!如果您阅读了一个问题,看到一个您认为错误的答案,并有一个您认为正确的答案,您为什么不投反对票?
  • @LibranCoder 我认为如果我们允许出于自我推销(或不)的利益而投反对票,SO 社区将无法区分基于质量的投反对票与否决答案之间的区别自我推销。我的 2 美分...
【解决方案6】:

如果您通过调用cell.addGestureRegognizer(_: _: _:) 将UILongPressGestureRecognizer 附加到cell,您应该通过以下操作从发件人那里检索单元格

let touchedView = sender.view as! UITableViewCell

无论如何,实现这一点的最佳方法通常是检查数据源,而不是调用 UITableViewDataSource 方法

【讨论】:

    【解决方案7】:

    您可以继承 UITableViewCell 并为索引路径添加一个 IVar,并在为 UITableView 数据源协议调用 cellForRowAtIndexPath 时设置它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-14
      相关资源
      最近更新 更多