首页 文章

Swift indexPathsForSelectedRows返回nil

提问于
浏览
3

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

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

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

为此,我像这里一样获取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?

非常感谢!

UPDATE 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()
    }

2 回答

  • 0

    来自indexPathsForSelectedRows documentation

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

    因此:

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

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

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

    return tableView.indexPathsForSelectedRows?.first
    

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

    return tableView.indexPathForSelectedRow
    

    已经存在了 .

  • 1

    你有这个bug,因为

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

    重新加载和取消选择您的行 .

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

    tableView.indexPathsForSelectedRows
    

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

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

    tableView.indexPathsForSelectedRows
    

相关问题