如何以编程方式在 iOS 中的多 select UITableView 中预置 select 单元格
How to Programmatically Pre-select Cells in a Multi-select UITableView in iOS
我使用 UITableView
让用户 select 从多个给定选项中允许多个 select 离子。我还希望用户稍后 return 到此视图并更改先前制作的 selection,这意味着我必须能够加载和初始化 table 与较早的 select离子。此外,用户可以点击“select-all”按钮,该按钮应以编程方式设置所有选项。
为此,我有一个布尔值数组,用于跟踪已检查和未检查的项目。但是,为了正确触发 didSelectRowAt
和 didDeselectRowAt
事件,table 视图还需要了解 selection 状态。所以我想出了两个选项,但我对这两个选项都不满意:
使用我自己的数组设置电池配件类型:
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
cell.textLabel!.text = items[indexPath.row].name
if items[indexPath.row].isSelected {
cell!.accessoryType = .checkmark
} else {
cell!.accessoryType = .none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell!.accessoryType = .checkmark
...
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell!.accessoryType = .none
...
}
这很好地切换了状态并更新了支持数组。它未能做到的是让 table 视图了解每个细胞的 selection 状态。因此,在重新加载时,会触发错误的 selection 事件(did select/did deselect),然后要求用户最初点击两次以更改状态。现在我可以通过处理 didSelectRowAt
和 didDeselectRowAt
中的两种状态来解决这个问题,但它与控件的状态相矛盾,并可能在以后导致问题。
让 table 视图跟踪状态:
这里,我替换了
if isSelected(index: indexPath.row) {
与
if let selectedRows = tableView.indexPathsForSelectedRows, selectedRows.contains(indexPath) {
这使 table 视图在内部保持更新,但我还没有找到一个好的方法来以编程方式设置状态,当用户 returns 到 table 时有一些预selected 项目或单击“select-all”时。尝试遍历我的数组并使用例如
设置 selections
`tableView.selectRow(at: IndexPath(row: index, section: 0), animated: false, scrollPosition: .none)`
(如对类似问题的回答中所建议的那样)在适用的情况下并未导致预期的结果。
使用预先 select 编辑的值初始化我的 table 并在单击“select-all”时更新它的最佳方法是什么?
您应该完全使用您的数据模型来管理它。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
// Assumption: item is a class, so changes are reflected in array as expected
let item = items[indexPath.row]
item.isSelected.toggle()
cell!.accessoryType = item.isSelected ? .checkmark : .none
}
这样一来,总有一个真实来源,即您的数据模型。您的 tableView 实例不需要为您记住任何内容,它由您提供的数据驱动。
如果采用这种方式,则无需实施 didDeselect
委托方法或将 allowsMultipleSelection
设置为 true
。
我使用 UITableView
让用户 select 从多个给定选项中允许多个 select 离子。我还希望用户稍后 return 到此视图并更改先前制作的 selection,这意味着我必须能够加载和初始化 table 与较早的 select离子。此外,用户可以点击“select-all”按钮,该按钮应以编程方式设置所有选项。
为此,我有一个布尔值数组,用于跟踪已检查和未检查的项目。但是,为了正确触发 didSelectRowAt
和 didDeselectRowAt
事件,table 视图还需要了解 selection 状态。所以我想出了两个选项,但我对这两个选项都不满意:
使用我自己的数组设置电池配件类型:
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath)
cell.textLabel!.text = items[indexPath.row].name
if items[indexPath.row].isSelected {
cell!.accessoryType = .checkmark
} else {
cell!.accessoryType = .none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell!.accessoryType = .checkmark
...
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell!.accessoryType = .none
...
}
这很好地切换了状态并更新了支持数组。它未能做到的是让 table 视图了解每个细胞的 selection 状态。因此,在重新加载时,会触发错误的 selection 事件(did select/did deselect),然后要求用户最初点击两次以更改状态。现在我可以通过处理 didSelectRowAt
和 didDeselectRowAt
中的两种状态来解决这个问题,但它与控件的状态相矛盾,并可能在以后导致问题。
让 table 视图跟踪状态:
这里,我替换了
if isSelected(index: indexPath.row) {
与
if let selectedRows = tableView.indexPathsForSelectedRows, selectedRows.contains(indexPath) {
这使 table 视图在内部保持更新,但我还没有找到一个好的方法来以编程方式设置状态,当用户 returns 到 table 时有一些预selected 项目或单击“select-all”时。尝试遍历我的数组并使用例如
设置 selections`tableView.selectRow(at: IndexPath(row: index, section: 0), animated: false, scrollPosition: .none)`
(如对类似问题的回答中所建议的那样)在适用的情况下并未导致预期的结果。
使用预先 select 编辑的值初始化我的 table 并在单击“select-all”时更新它的最佳方法是什么?
您应该完全使用您的数据模型来管理它。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
// Assumption: item is a class, so changes are reflected in array as expected
let item = items[indexPath.row]
item.isSelected.toggle()
cell!.accessoryType = item.isSelected ? .checkmark : .none
}
这样一来,总有一个真实来源,即您的数据模型。您的 tableView 实例不需要为您记住任何内容,它由您提供的数据驱动。
如果采用这种方式,则无需实施 didDeselect
委托方法或将 allowsMultipleSelection
设置为 true
。