我有一个tableview,其中有tableviewcells,如...
点击此tableview单元格后,它会展开以显示更多按钮,如此...
但是如果我在上面的搜索栏中进行搜索,并且在我得到结果后,当我点击tableviewcell时,它会崩溃,显示一些错误信息,如
NSInternalInconsistencyException',原因:'无效更新:第0节中的行数无效。更新后的现有部分中包含的行数(34)必须等于包含的行数更新前的那一段......
可能是什么原因......?
此外,这是点击单元格时的代码..
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? ProductListTableViewCell
else { return }
switch cell.isExpanded
{
case true:
self.expandedRows.remove(indexPath.row)
case false:
self.expandedRows.insert(indexPath.row)
}
cell.isExpanded = !cell.isExpanded
tableview.beginUpdates()
tableview.endUpdates()
}
编辑1 :这是numberOfRowsInSection
...
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if noSearchChar1 == true {
return filtered.count
}
if filtered.count == 0 && self.appDelegate.searchBarTapFlag == true {
// searchActive = false
if deleteBtnTapped == true {
return filtered.count
}
return newProdDetails.count
}
if(searchActive) {
return filtered.count
}
return newProdDetails.count
}
编辑2:这是filtered
数组获取某些数据的代码...
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText != "" {
charInSearchBar = true
//filter the results
searchActive = true
filtered = self.newProdDetails.filter({( data : NewProduct) -> Bool in
return (data.name!.lowercased().contains(searchText.lowercased()))
}) //'filtered' array gets data here.
if(filtered.count == 0){
noSearchChar1 = true //this flag is to prevent no data showing on click of back btn.
noSearchChar = true
} else {
searchActive = true;
}
tableview.reloadData() //tableview is reloaded
} else {
noSearchChar1 = false
searchActive = false
self.tableview.reloadData()
}
}
答案 0 :(得分:0)
因为您正在更改numberOfRowsInSection:
返回的行数而导致崩溃,但您没有给表格视图任何理由预期行数会发生变化。
某处(代码未显示)您将数据放入filtered
,这会导致numberOfRowsInSection:
返回filtered.count
而不是newProdDetails.count
。这不会导致立即崩溃,因为tableview在此时不会调用numberOfRowsInSection:
。
当您选择一行并调用beginUpdates
/ endUpdates
时,tableview会调用numberOfRowsInSection:
,然后您会因为行数已更改但tableview未预期而崩溃改变。
当您在过滤后的数据和未过滤的数据之间切换(或对过滤后的结果进行更改)时,您需要致电reloadData
。
此外,您无法在单元格中存储isExpanded
值,因为将重用单元格对象。您需要将其存储在某个地方的数据模型中。存储indexPath
将不起作用,因为在过滤数据时行数会发生变化。
答案 1 :(得分:-1)
在didSelectRowAt
的switch语句中,删除旧单元格后没有再插入,因此单元格数不一样。
当你调用beginUpdates时,编译器需要插入/删除行等操作,但在你的情况下,你没有,然后只是endUpdates,哪个编译器将视为没有更新,因此你的代码删除或插入上面将触发错误"行数不等于"
只需将switch语句放在
中即可 tableview.beginUpdates()
switch cell.isExpanded
{
case true:
self.expandedRows.remove(indexPath.row)
case false:
self.expandedRows.insert(indexPath.row)
}
tableview.endUpdates()
应该有效
如果未在此块内进行插入,删除和选择调用,则行计数等表属性可能会变为无效。 fyi:https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates