SwiftData模型观察与UndoManager的撤销更新异常问题
SwiftData 模型观察与 UndoManager 同步问题
我创建了最小复现示例,用于展示SwiftData模型观察与UndoManager的同步问题。项目包含简单的NavigationSplitView、可持久化的Item SwiftData模型,且已启用UndoManager。
问题现象
- SwiftData模型
Item可正常被观察:在DetailView中修改日期时,ListElementView和DetailView均能正常更新视图。 - 使用⌘+Z执行撤销操作时:侧边栏的删除/插入操作可即时生效,
ContentView能正确观察到变化;但修改timestamp后执行撤销,相关视图无法即时更新显示撤销结果。
补充细节
- 切换侧边栏选中项后,
DetailView会显示timestamp修改的撤销结果 - 重启应用后,
ListElementView会显示timestamp修改的撤销结果 - 移除
ListElementView(直接在List中编写Text视图,不做封装)时,侧边栏可即时观察到timestamp修改的撤销结果
推测:UndoManager执行撤销操作时,未通过items查询触发ContentView的重绘?
相关代码
ContentView
struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var items: [Item] @State private var selectedItems: Set<Item> = [] var body: some View { NavigationSplitView { List(selection: $selectedItems) { ForEach(items) { item in ListElementView(item: item) .tag(item) } .onDelete(perform: deleteItems) } .navigationSplitViewColumnWidth(min: 180, ideal: 200) .toolbar { ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { if let item = selectedItems.first { DetailView(item: item) } else { Text("Select an item") } } .onDeleteCommand { deleteSelectedItems() } } private func addItem() { withAnimation { let newItem = Item(timestamp: Date()) modelContext.insert(newItem) } } private func deleteItems(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(items[index]) } } } private func deleteSelectedItems() { for selectedItem in selectedItems { modelContext.delete(selectedItem) selectedItems.remove(selectedItem) } } }
ListElementView
struct ListElementView: View { @Bindable var item: Item var body: some View { Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") } }
DetailView
struct DetailView: View { @Bindable var item: Item var body: some View { Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) DatePicker(selection: $item.timestamp, label: { Text("Change Date:") }) } }
Item 模型
@Model final class Item { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
内容的提问来源于stack exchange,提问作者Maschina
相关产品推荐
相关产品推荐

