我正在制作一个音乐类型选择应用程序,当我去我的桌子选择类型时,我选择一行,它从我的选择中选择一个大约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
}
}
答案 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()