【问题标题】:indexPathForSelectedRow returning nilindexPathForSelectedRow 返回 nil
【发布时间】:2012-01-31 01:30:51
【问题描述】:

我有一个带有 segue 的 UITableViewController,我试图在其中获取当前选定的行:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([[segue identifier] isEqualToString:@"EditFilterElementSegue"]){
        // Get the element that was clicked and pass it to the view controller for display
        NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
        Element *element = [fetchedResultsController objectAtIndexPath:selectedIndexPath];
        FilterElementTableViewController *vc = segue.destinationViewController;
        vc.filter = filter;
        vc.element = element;
    }
}

问题是 indexPathForSelectedRow 返回 nil。文档说“如果索引路径无效”返回 nil 。如果我添加:

        [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:0];
        selectedIndexPath = [self.tableView indexPathForSelectedRow];

selectedIndexPath 有效。所以,我目前假设该行以某种方式被取消选中。谁能告诉我如何确定是否是这种情况以及可能是什么原因造成的?

在我转换为使用 NSFetchedResultsController 之前,这段代码运行良好(否则它可以工作)。我还在其他几个可以正常工作的表视图控制器中使用 indexPathForSelectedRow(其中一个也使用 NSFetchedResultsController)。

我也尝试过闯入 didSelectRowAtIndexPath,但同样的事情也发生在那里。 (预期,因为它是在 prepareForSegue 之后调用的。)

【问题讨论】:

    标签: ios uitableview null


    【解决方案1】:

    一个可能的原因是您在 UITableViewDelegate 方法之一中编写了一些东西 -

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

    常用的做法是deselect the row刚刚被选中。

    更新:

    在 Swift 4.2 中,xcode 10:

    只需评论该行

    tableView.deselectRow(at: indexPath, animated: true)
    

    在函数中

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    

    【讨论】:

    • 对我来说,我正在取消选择我的行。 'Doh!
    【解决方案2】:

    可能对其他人有所帮助的东西 - 如果您在表格视图上调用 reloadData(),它会取消 indexPathForSelectedRow

    【讨论】:

    • 这个出人意料的简单发现为我节省了几个小时 ;)
    【解决方案3】:

    请确保,在获取所选行的索引路径之前,您没有调用 deselectRowAtIndexPath 方法。

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [tableView deselectRowAtIndexPath:indexPath animated:YES]; //add this line after setting indexPath
    }
    

    【讨论】:

    • reloadData 也可能导致取消选择行
    【解决方案4】:

    好的,就我而言,我是通过 show segue 从情节提要中的 UIButton 调用的。

    并删除以下行:

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

    以下 2 行对我有用:

    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

    希望我的案例“从 CELL 上的 UIButton 调用 segue”也适用于其他人。

    【讨论】:

    • 哇,这太完美了,我正在做类似的事情。我不得不重新加载一个特定的单元格,但是由于滚动时该部分发生了变化,我无法再更新了。这是我与您的答案一起使用的内容 NSArray *indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexPathSectionRow.row inSection:indexPathSectionRow.section ]]; [self.nationalTableView reloadRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationFade];
    【解决方案5】:

    好吧,底线是故事板中的场景搞砸了。

    为了弄清楚这一点,我删除了 segue 并创建了一个全新的空 UITableViewController 类,并且只添加了足够的代码,以便我可以单击一行并查看 indexPathForSelectedRow。它仍然是零。

    然后我在情节提要中创建了一个新的 UITableViewController 并替换了现有的。现在 indexPathForSelectedRow 工作了。

    我把所有的类代码和原型单元都复制了一遍,它仍然有效!

    出于好奇,我查看了这两个场景的情节提要源代码,发现不起作用的场景比新场景长得多。查看故事板大纲很明显为什么,并且令人惊讶的是它完全有效。而且,现在我记得在剪切和粘贴原型单元格时遇到了麻烦。我想我应该更频繁地查看大纲模式。请看下面的屏幕截图(视觉场景看起来相同):

    【讨论】:

      【解决方案6】:

      当我在代码中用 UIViewController 类替换 UITableViewController 类并且没有更新情节提要时,我也遇到了这个问题,即我没有用 UIViewController 情节提要替换情节提要中的 UITableViewController 占位符。

      【讨论】:

        【解决方案7】:

        Swift 4.2

        您必须告诉 tableView 选择了哪个单元格。

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else { return UITableViewCell() }
        
            let data = products[indexPath.section][indexPath.row]
            cell.update(data: data)
        
            // Don't use cell.isSelected = true
            if data == selectedData {
                tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
            }
            return cell
        }
        

        【讨论】:

          【解决方案8】:

          在我的例子中,UITableViewController 在 Storyboard 中选择了 Clear on Appearance,如下所示

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-06-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-18
            • 2019-06-20
            • 2017-12-16
            相关资源
            最近更新 更多