Swift indexPathsForSelectedRows返回nil

时间:2017-06-07 10:52:21

标签: ios swift uitableview

我正在研究一个tableView,目标是实现一个可扩展/可折叠的tableView单元格。细胞数量是完全动态的。

我有一些工作,但有一个小问题。我正在使用didSelectRowAtIndexPath来切换展开/折叠单元格。那么现在发生的是通过点击单元格上的任何位置来执行切换。 : - (

在单元格内部,我有两个UIViews(精确的标题和细节)。我需要切换展开/折叠才能在我点击标题而不是整个单元格时工作。

为此,我像这里一样获取indexPath,但由于indexPathsForSelectedRows返回nil,因此无法工作。

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }


    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myVouchers.count
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if selectedIndex == indexPath.row {
            return 150.0
        }
        else {
            return 40.0
        }
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        cell = tableView.dequeueReusableCellWithIdentifier("CollapsedCell", forIndexPath: indexPath) as! CollapsedCell

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(VoucherDetailViewController.expandCell(_:)))
        (cell as! CollapsedCell).headerView.addGestureRecognizer(tapGestureRecognizer)

        return cell
    }

    func getIndexPathForSelectedCell() -> NSIndexPath? {

        var indexPath: NSIndexPath?

        if tableView.indexPathsForSelectedRows?.count > 0 {   //**nil is returned here**
            indexPath = (tableView.indexPathsForSelectedRows?[0])! as NSIndexPath
        }
        return indexPath
    }

    func expandCell(sender: UITapGestureRecognizer) {
        if let myIndexPath = getIndexPathForSelectedCell() {
            if selectedIndex == myIndexPath.row {
                selectedIndex = -1
            }
            else {
                selectedIndex = myIndexPath.row
            }

            self.tableView.beginUpdates()
            self.tableView.reloadRowsAtIndexPaths([myIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
            self.tableView.endUpdates()
        }
    }

有人能给我一个线索,为什么indexPathsForSelectedRows返回nil?

非常感谢!

更新1: Current Working demo

当我在didSelectRowAtIndexPath中添加扩展单元格逻辑并删除我的tapGestureRecognizer以查看单元格内的视图时 - 它看起来像这样 -

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        if selectedIndex == indexPath.row {
            selectedIndex = -1
        }
        else {
            selectedIndex = indexPath.row
        }

        self.tableView.beginUpdates()
        self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        self.tableView.endUpdates()
    }

3 个答案:

答案 0 :(得分:1)

来自indexPathsForSelectedRows documentation

  

如果没有选定的行,则此属性的值为nil。

因此:

guard let selectedRows = tableView.indexPathsForSelectedRows else {
   return nil
}

return selectedRows[0]

(不需要检查count,该方法永远不会返回空数组。)

顺便说一下,您可以使用以下方法简化条件:

return tableView.indexPathsForSelectedRows?.first

或者,如果您的表格不支持多项选择,请直接致电:

return tableView.indexPathForSelectedRow

已经存在。

答案 1 :(得分:0)

你有这个错误,因为

onEachFeature

重新加载并取消选择您的行。

您只需选择行,然后重新加载行(此操作将取消选择此行),之后您希望使用

获取所选行
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)

但是表格视图此时没有任何选定的行。

作为解决方案,您可以将选定的indexPath存储在新变量中,并使用此变量代替

tableView.indexPathsForSelectedRows

答案 2 :(得分:0)

  

Sulthan 所述,请尝试使用以下代码代替重新加载

tableView.beginUpdates()
tableView.endUpdates()