如何解决何时调用 tableView.selectRow 以避免 UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate
在实现对 UITableView
的多行选择的支持时,我使用了在 rowSelectionState
和 didSelectRow
期间管理的私有变量 diddeselectRow
。然后,rowSelectionState
的当前状态用于通过调用 configureCellSelectionState()
cellForRowAt
来控制向用户显示正确选择的行。从技术上讲,从 iOS 14.4 开始,这完成了它应该做的事情,但需要注意的是,iOS 会在 XCode 中转储一堆 UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate
警告。
private var rowSelectionState = [IndexPath: Bool]()
func configureCellSelectionState(_ indexPath: IndexPath) {
guard tableView.isEditing else { return }
if rowSelectionState[indexPath] ?? false {
tableView.selectRow(at: indexPath,animated: false,scrollPosition: .none)
} else {
tableView.deselectRow(at: indexPath,animated: false)
}
}
override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
if tableView.isEditing {
rowSelectionState[indexPath] = true
}
}
override func tableView(_ tableView: UITableView,diddeselectRowAt indexPath: IndexPath) {
if tableView.isEditing {
rowSelectionState[indexPath] = false
}
}
override func setEditing(_ editing: Bool,animated: Bool) {
super.setEditing(editing,animated: animated)
if !editing {
rowSelectionState.removeAll()
}
}
在 configureCellSelectionState()
内部调用 cellForRowAt
是它最初的编写方式。
override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: rowCellId,for: indexPath)
configureCellSelectionState(indexPath)
return cell
}
在仔细观察警告流后,我在 StackOverflow 的一些搜索中调用了 configureCellSelectionState()
而不是 willdisplay
内部的 cellForRowAt
。不幸的是,警告仍然存在。
override func tableView(_ tableView: UITableView,willdisplay cell: UITableViewCell,forRowAt indexPath: IndexPath) {
configureCellSelectionState(indexPath)
}
示例警告:
2021-02-09 09:12:14.119983-0500 XXX [55266:1705708] [Assert]
Attempted to call -cellForRowAtIndexPath: on the table view while it was in the process of updating its visible cells,which is not allowed.
Make a symbolic breakpoint at UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate to catch this in the debugger and see what caused this to occur.
Perhaps you are trying to ask the table view for a cell from inside a table view callback about a specific row?
Table view: <UITableView: 0x7b7800045c00; frame = (0 0; 390 844); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7b0c000fee50>; layer = <CALayer: 0x7b08002be520>; contentOffset: {0,-143}; contentSize: {390,264}; adjustedContentInset: {143,143,0}; dataSource: <XXX.YYYTableViewController: 0x7b640006b800>>
那么问题是,在避免 UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate
警告的同时实现这种功能的“正确”方法是什么?
解决方法
不要在显示单元格时调用 tableView.selectRow
或 tableView.deselectRow
,而是从视图控制器的 viewDidLoad
调用它。或者也许在设置 rowSelectionState
的值之后,如果已经加载视图控制器之后发生这种情况。
问题在于,当您尝试更改选择状态时,您处于 UITableView
委托方法中,因此无法正常工作。
另请注意,您可以检查 indexPathsForSelectedRows
上的 UITableView
属性,这样当您对 rowSelectionState
进行更改时,您只需更新那些需要它的行的选择状态.但同样,当您处于 UITableView
委托方法中间时不要这样做。
此外,从外观上看,您正在尝试使用 rowSelectionState
来跟踪哪些已处于选定状态,因此您可能只需要引用 indexPathsForSelectedRows
属性。>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。