UITableViewCell无意中勾选了不需要的行

时间:2018-02-13 02:19:42

标签: ios swift uitableview

我正在制作一个音乐类型选择应用程序,当我去我的桌子选择类型时,我选择一行,它从我的选择中选择一个大约10个左右的随机行。

我的选择代码是:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let genresFromLibrary = genrequery.collections
    let rowitem = genresFromLibrary![indexPath.row].representativeItem
    print(rowitem?.value(forProperty: MPMediaItemPropertyGenre) as! String
    )
    if let cell = tableView.cellForRow(at: indexPath)
    {
        cell.accessoryType = .checkmark
    }
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath)
    {
        cell.accessoryType = .none
    }
}

2 个答案:

答案 0 :(得分:1)

默认情况下,在调用cellForRowAtIndexPath时会重复使用单元格。当您不跟踪已选择的indexPath时,这会导致单元格具有错误的数据。您需要跟踪当前选择的索引路径,以便在表格视图中显示相应的附件类型。

这样做的一种方法是在UITableViewController中有一个属性,它只存储所选单元格的索引路径。它可以是数组或集合。

var selectedIndexPaths = Set<IndexPath>()

当您在didSelectRowAt上选择一行时,请在selectedIndexPaths中添加或删除该单元格,具体取决于索引路径是否已在数组中:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if selectedIndexPaths.contains(indexPath) {
         // The index path is already in the array, so remove it.
         selectedIndexPaths.remove(indexPathIndex)
    } else {
         // The index path is not part of the array
         selectedIndexPaths.append(indexPath)
    }

    // Show the changes in the selected cell (otherwise you wouldn't see the checkmark or lack thereof until cellForRowAt got called again for this cell).
    tableView.reloadRows(at: [indexPath], with: .none)
}

完成此操作后,在cellForRowAtIndexPath上,检查indexPath是否在selectedIndexPaths数组中,以选择accessoryType

if selectedIndexPaths.contains(indexPath) {
    // Cell is selected
    cell.accessoryType = .checkmark
} else {
    cell.accessoryType = .none
}

这应解决看似随机的单元格每隔10个单元格检查一次的问题(这不是随机的,只是带有复选标记的单元格被重用)。

答案 1 :(得分:0)

因为cellForRow返回您生成的缓存单元格。当滚出屏幕时,单元格的顺序会发生变化,单元格会被重复使用。所以它似乎随机选择&#34;。

请使用cellForRow,而不是记录选择数据。

此处的代码可在单个视图操场中使用。

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController, UITableViewDataSource, UITableViewDelegate {

    let tableView = UITableView()
    var selection: [IndexPath: Bool] = [:]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        view.addSubview(tableView)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        tableView.frame = self.view.bounds
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "c")
        if let sc = cell {
            sc.accessoryType = .none
            let isSelected = selection[indexPath] ?? false
            sc.accessoryType = isSelected ? .checkmark : .none
            return sc
        }
        return UITableViewCell(style: .default, reuseIdentifier: "c")
    }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cell.textLabel?.text = NSNumber(value: indexPath.row).stringValue
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        selection[indexPath] = true
        tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
    }

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 30
    }

}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()