You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:04:17