indexPathForSelectedRow返回nil虽然我有一个以编程方式选择的单元格

时间:2016-09-14 12:57:32

标签: ios swift uitableview

我有UITableView我加载了一些应用程序设置。我需要将表格单选,并且由于表格保存设置,因此可能会根据设置启用状态以编程方式选择某个单元格。

目前,我遇到了一种奇怪的行为,如果我以编程方式选择一个单元格,那么indexPathForSelectedRow会返回nil(当它应该返回我选择的单元格的索引时),因此当我点击时第二个单元格(更改当前选定的设置)我最终选择了两个单元格(即使我在tableView对象中将allowMultipleSelection设置为false)。

这是我的代码:

override func viewDidLoad() {
    tableView.allowsMultipleSelection = false
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("myCell")

    if let cell = cell {
        // tableObject is an array containing settings model
        let row = tableObject[indexPath.row]
        cell.textLabel!.text = row.settingValue
        if row.selected {
            cell.setSelected(true, animated: false)
            cell.accessoryType = .Checkmark
        }
        cell.tag = row.id
    }

    return cell!
}

override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
    // oldIndex is always nil for the cell I called setSelected in cellForRowAtIndexPath
    if let oldIndex = tableView.indexPathForSelectedRow {
        if let oldCell = tableView.cellForRowAtIndexPath(oldIndex) {
            tableView.deselectRowAtIndexPath(oldIndex, animated: true)
            oldCell.accessoryType = .None           
        }
    }

    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        cell.setSelected(true, animated: true)
        cell.accessoryType = .Checkmark
    }

    return indexPath
}

override func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        cell.accessoryType = .None
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
    return indexPath
}

知道如何一次只选择一个单元格吗?

谢谢!

3 个答案:

答案 0 :(得分:0)

创建一个类似

的数组
var arrSelectCell = [NSIndexPath]()

并在didSelectRowAtIndexPath处执行以下代码:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if arrSelectCell.contains(indexPath) {
        if let oldCell = tableView.cellForRowAtIndexPath(indexPath) {

                if let index = arrSelectCell.indexOf(indexPath) {
                    arrSelectCell.removeAtIndex(index)
                }
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
            oldCell.accessoryType = .None
        }

    }
    else
    {
        arrSelectCell.append(indexPath)
        if let selectCell = tableView.cellForRowAtIndexPath(indexPath) {
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
            selectCell.accessoryType = .Checkmark
        }


    }    

并且也不要忘记在cellForRowAtIndexPath中设置代码,以便在重用单元格之后检查已检查和未检查的单元格维护。因此,需要编写的代码很少,如下所示。

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

            let cell = tableView.dequeueReusableCellWithIdentifier("serchCell", forIndexPath: indexPath) as! SearchTableViewCell

            if arrSelectCell.contains(indexPath)
            {
                    cell.accessoryType = .Checkmark
            }
            else
            {
                    cell.accessoryType = .None
            }

            return cell
        }

答案 1 :(得分:0)

如果其他人遇到同样的行为,似乎通过cell.setSelected()选择单元格与调用tableView.selectRowAtIndexPath()方法不同。选择具有最新功能的行可以完美地完成工作并解决问题。

答案 2 :(得分:0)

请注意,调用tableView.reloadData()会将tableView.indexPathForSelectedRow重置为nil。

这里是如何通过tableView.indexPathForSelectedRow完成表格查看单一选择:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.accessoryType = tableView.indexPathForSelectedRow == indexPath ? .checkmark : .none
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        if let visiblePaths = tableView.indexPathsForVisibleRows
        {
            for visibleIndexPath in visiblePaths
            {
                let cell = tableView.cellForRow(at: visibleIndexPath)
                if visibleIndexPath == indexPath
                {
                    cell?.accessoryType = .checkmark
                }
                else
                {
                    cell?.accessoryType = .none
                }
            }
        }
    }