SwiftData @Query变更通知问题:新增对象后SwiftUI列表未更新
解决SwiftData @Query新增对象时列表不更新的问题
方案1:监听@Query数组的变化
直接通过.onChange(of: events)监听events数组的所有变更(包括新增、删除、修改),触发过滤排序逻辑更新data:
@State var data: [Date:[Event]] = [:] @Query(sort: \Event.startTime) private var events: [Event] @ObservedObject var filterManager: FilterManager // 确保已正确注入该对象 List { // 原有列表内容保持不变 } .onAppear(){ updateData() } .onReceive(filterManager.objectWillChange){ updateData() } .onChange(of: events) { _, _ in updateData() } // 提取重复逻辑到单独方法,简化代码 private func updateData() { data = filterManager.sortedEvents(events: filterManager.filteredEvents(events: events)) }
方案2:将data改为计算属性
不需要手动维护@State变量,直接用计算属性基于events和过滤参数动态生成结果,依赖项变化时会自动触发刷新:
@Query(sort: \Event.startTime) private var events: [Event] @ObservedObject var filterManager: FilterManager // 计算属性自动响应events和filterManager的变化 private var data: [Date:[Event]] { filterManager.sortedEvents(events: filterManager.filteredEvents(events: events)) } List { ForEach(Array(data.keys).sorted(by: <), id: \.self) { day in // 原有列表内容保持不变 } }
这个方案最简洁,省去了手动更新data的逻辑,SwiftUI会自动跟踪计算属性的依赖(events和filterManager的可观察属性),任何依赖变化时都会自动刷新列表。
方案3:订阅events的objectWillChange事件
@Query返回的集合遵循Observable协议,可以直接订阅它的底层变更信号:
@State var data: [Date:[Event]] = [:] @Query(sort: \Event.startTime) private var events: [Event] @ObservedObject var filterManager: FilterManager List { // 原有列表内容保持不变 } .onAppear(){ updateData() } .onReceive(filterManager.objectWillChange){ updateData() } .onReceive(events.objectWillChange) { updateData() } private func updateData() { data = filterManager.sortedEvents(events: filterManager.filteredEvents(events: events)) }
该方案和方案1效果类似,但直接订阅底层变更信号,适合需要更精细控制的场景。
内容的提问来源于stack exchange,提问作者Luuk D. Jansen
相关产品推荐
相关产品推荐

