UITableView搜索时重载除前两分区外的分区崩溃问题求助
解决UITableView重载Sections时的崩溃问题
你的崩溃原因很明确:调用reloadSections时,你传入的分区范围是基于更新前的UITableView分区总数,但此时你已经修改了countDic,导致更新后的分区总数和旧的不匹配,从而触发了越界错误。
举个例子:假设更新前你的countDic有4个分区(0、1、2、3),搜索后你更新了countDic,现在只有3个分区(0、1、2)。但你还是用2..<self.TblView.numberOfSections(此时numberOfSections还是旧的4)生成IndexSet,这就会包含分区3——但更新后这个分区已经不存在了,自然会崩溃。
下面是具体的修复步骤:
1. 确保countDic的更新逻辑正确
每次搜索时,你需要完全重建countDic,而不是只更新部分值,避免出现key缺失或多余的情况:
// 搜索时的数据源更新逻辑 func updateSearchResults() { // 1. 先获取过滤后的数据源(比如filteredArray和filteredArray1) let filteredArray = ... // 你的搜索过滤结果 let filteredArray1 = ... // 对应动态分区的数据源 // 2. 清空并重建countDic self.countDic.removeAll() // 添加固定分区0和1 self.countDic.updateValue(1, forKey: "0") self.countDic.updateValue(0, forKey: "1") // 添加动态分区(从2开始) for i in 0..<filteredArray1.count { self.countDic.updateValue(filteredArray.count, forKey: "\(i + 2)") } }
2. 使用更新后的分区总数生成IndexSet
不要依赖self.TblView.numberOfSections(它是旧值,因为tableView还没刷新),直接用刚更新的countDic.count来确定需要重载的分区范围:
// 在UITextField的shouldChangeCharactersIn方法中 updateSearchResults() let newSectionCount = self.countDic.count // 生成从分区2到最后一个分区的IndexSet let reloadIndexSet = IndexSet(integersIn: 2..<newSectionCount) self.TblView.reloadSections(reloadIndexSet, with: .bottom)
3. 处理动态分区数量变化的情况
如果你的动态分区(分区2及以后)的数量会随着搜索结果变化(比如filteredArray1的元素数变多/变少),直接用reloadSections还是会报错,因为分区总数变了。这时候需要先增删分区,再重载:
updateSearchResults() let oldSectionCount = self.TblView.numberOfSections let newSectionCount = self.countDic.count self.TblView.beginUpdates() // 处理分区删除 if newSectionCount < oldSectionCount { let deleteRange = newSectionCount..<oldSectionCount self.TblView.deleteSections(IndexSet(integersIn: deleteRange), with: .fade) } // 处理分区插入 else if newSectionCount > oldSectionCount { let insertRange = oldSectionCount..<newSectionCount self.TblView.insertSections(IndexSet(integersIn: insertRange), with: .fade) } // 重载需要更新的动态分区 let reloadRange = 2..<newSectionCount self.TblView.reloadSections(IndexSet(integersIn: reloadRange), with: .bottom) self.TblView.endUpdates()
4. 优化numberOfRowsInSection的安全性
避免强制解包countDic的值,防止因为key缺失导致崩溃:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 如果找不到对应key,返回0作为默认值 return countDic["\(section)"] ?? 0 }
这样修改后,你的UITableView就能在搜索时安全地重载动态分区了。
内容的提问来源于stack exchange,提问作者Vishal N
相关产品推荐
相关产品推荐

