繁体   English   中英

indexPathForSelectedRow 返回 nil

[英]indexPathForSelectedRow returning nil

我有一个带有 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 之后调用的。)

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

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

deselect the row刚刚deselect the row是一种常见的做法。

更新:

在 Swift 4.2 中,xcode 10:

只需注释该行

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

在函数中

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

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

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

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

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

并删除以下行:

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

以下两行对我有用:

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

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

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

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

然后我在故事板中创建了一个新的 UITableViewController 并替换了现有的。 现在 indexPathForSelectedRow 起作用了。

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

出于好奇,我查看了两个场景的故事板源,并注意到无效的场景比新场景长得多。 看看情节提要大纲,原因很明显,而且令人惊讶的是它竟然奏效了。 而且,现在我记得在剪切和粘贴原型单元格时遇到了麻烦。 我想我应该更频繁地查看大纲模式。 请参阅下面的屏幕截图(视觉场景看起来相同):

故事板截图

我也遇到了这个问题,当我在代码中用 UIViewController 类替换 UITableViewController 类时,没有更新故事板,即我没有用 UIViewController 故事板替换故事板中的 UITableViewController 占位符。

斯威夫特 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
}

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

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM