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

UITableView动态分区自定义下拉框滚动重复数据问题求助

解决UITableView复用导致自定义下拉选中数据重复的问题

1. 重构选中数据的存储结构

你当前用全局的chapData存储选中项,无法区分不同分区的选择,这是复用混乱的核心原因。需要改成按分区索引绑定的存储结构:

// 情况1:分区数量固定时,用数组初始化空数据
var sectionChapterData: [[DropDownModel]] = Array(repeating: [], count: 你的分区总数)

// 情况2:分区动态变化时,用字典更灵活
var sectionChapterData: [Int: [DropDownModel]] = [:]

2. 修改代理回调,传递分区索引

在代理链中加入分区编号,确保视图控制器知道是哪个分区的选中数据:

  • 自定义Cell中的代理方法修改:
func passChapterData(chapData: [DropDownModel]) {
    // 把当前cell绑定的分区号一起传给控制器
    delegateChapter?.chapterDropdownView(chapData: chapData, forSection: self.section)
}
  • 视图控制器中的代理方法修改:
// 新增分区参数,更新对应分区的选中数据
func chapterDropdownView(chapData: [DropDownModel], forSection section: Int) {
    sectionChapterData[section] = chapData
    // 字典写法:sectionChapterData[section] = chapData
}

3. 修正cellForRowAt的数据绑定逻辑

去掉不必要的DispatchQueue.main.async,直接根据当前分区索引获取对应数据:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CellGenerateTestpaper", for: indexPath) as! CellGenerateTestpaper
    
    cell.questionTypeModel = questionTypeModel
    cell.delegate = self
    cell.delegateChapter = self
    cell.delegateDifficulty = self
    cell.section = indexPath.section
    cell.isSelf = isSelfGrading
    cell.isNormal = isNormal
    
    // 绑定当前分区的专属选中数据
    let selectedChapters = sectionChapterData[indexPath.section] 
    // 字典写法:sectionChapterData[indexPath.section] ?? []
    cell.txtChapters.selectedDropDownItems = selectedChapters
    
    cell.updateDropdown(difficultyData: difficultyArray, chaptersData: chaptersArray)
    return cell
}

4. 完善Cell的prepareForReuse方法

在CellGenerateTestpaper类中重写该方法,重置控件状态,避免复用旧数据:

override func prepareForReuse() {
    super.prepareForReuse()
    // 清空下拉视图选中项
    txtChapters.selectedDropDownItems = []
    // 如果有文本框等其他控件,也在这里重置
    // txtInput.text = ""
}

关键说明

  • 核心问题是全局变量无法区分分区数据,改成按分区存储后,每个cell只读取对应分区的选中项。
  • 移除DispatchQueue.main.async是因为cellForRowAt本身就在主线程执行,异步赋值会导致cell先显示复用的旧数据,快速滚动时出现错乱。
  • prepareForReuse确保cell被复用时彻底清空之前的状态,避免残留旧内容。

内容的提问来源于stack exchange,提问作者Sushil Dhital

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:41:16