SwiftUI macOS Table条目滚出视野后更新异常重复显示问题咨询
问题原因
这个是 macOS 12 Monterey Beta 1/2 版本中 SwiftUI Table 组件的通用原生缺陷,大量开发者在相同版本环境下均可复现该问题,根源是组件的单元格复用逻辑存在问题:Table 为了提升滚动性能会复用离屏的单元格视图,但 Beta 版本中没有正确关联单元格与对应数据条目的唯一标识,排序后也不会主动刷新不可视区域的单元格内容,滚动时直接复用了旧的渲染结果,就会出现单个条目重复显示的问题。同期 Beta 版本中 List 的复用逻辑已经完成适配,所以替换为 List 后问题消失。
解决方案
如果需要继续使用 Table 支持多列布局,可以用以下临时方案规避问题,升级到 macOS 12 正式版 + Xcode 13 正式版后该缺陷已被官方修复,无需额外适配:
- 单元格显式绑定标识(推荐,无滚动位置丢失问题)
将TableColumn的内容构造改为显式闭包,给单元格内容绑定对应条目的唯一ID,强制单元格在数据变化时单独刷新:
Table(sortedData) { // 不使用默认的value构造,改为自定义内容闭包 TableColumn("Text") { item in Text(item.text) .id(item.id) } }
- 全局强制刷新Table
给Table整体绑定ID,当数据源变化时强制整个组件重绘,适合数据量较小的场景:
Table(sortedData) { TableColumn("Text", value: \.text) } .id(data.hashValue) // 也可以绑定data.count,只要数据源变化时ID更新即可
- 主动触发刷新
在添加数据的逻辑结束后,手动触发一次数据源刷新,打乱复用缓存:
private func addItem(longString: Bool) { withAnimation { data.append(TestStruct(text: longString ? "This is long so you can differentiate better" : "Short")) // 临时强制重排一次,触发Table更新 let temp = data data = [] data = temp } }
内容的提问来源于stack exchange,提问作者newswiftuser
相关产品推荐
相关产品推荐

