indexPathForSelectedRow返回nil

时间:2012-01-31 01:30:51

标签: ios uitableview null

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

8 个答案:

答案 0 :(得分:25)

可能的原因是你在其中一个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)

答案 1 :(得分:18)

可能有助于他人的事情 - 如果您在表格视图中致电reloadData(),则会对indexPathForSelectedRow进行诽谤。

答案 2 :(得分:10)

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

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

答案 3 :(得分:2)

Ok在我的情况下,我是通过show segue在故事板中从UIButton打来的电话。

删除以下行:

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

以下2行为我工作:

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

希望我的案例&#34;在CELL上调用来自UIButton的segue&#34;也适用于其他人。

答案 4 :(得分:1)

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

为了解决这个问题,我删除了segue并创建了一个全新的空UITableViewController类,并且只添加了足够的代码,因此我可以单击一行并查看indexPathForSelectedRow。它仍然没有。

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

我复制了所有的类代码,并将原型单元格复制过来,它仍然有效!

出于好奇,我查看了两个场景的故事板来源,并注意到无法工作的场景比新场景长得多。看一下故事板大纲,很明显为什么,而且令人惊讶的是它的功能。而且,现在我记得切割时遇到了麻烦。粘贴原型细胞。我猜我应该更频繁地看一下轮廓模式。请参见下面的屏幕截图(视觉场景看起来相同):

Storyboard screen shot

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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
}

答案 7 :(得分:-1)

在我的情况下,是 UITableViewController 在情节提要板上选择了Clear on Appearance,如下所示

enter image description here