从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新

Posted

技术标签:

【中文标题】从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新【英文标题】:SwiftUI TabView with List not refreshing after objected deleted from / added to Core Data 【发布时间】:2020-03-26 01:46:53 【问题描述】:

说明:

当列表中的对象(从 fetchrequest 创建)从上下文中删除并保存上下文时,列表不会正确更新。

错误:

线程 1:致命错误:在展开可选值时意外发现 nil(在下面的第 5 行抛出)

struct DetailView: View   
    @ObservedObject var event: Event  

    var body: some View   
        Text("\(event.timestamp!, formatter: dateFormatter)")  
            .navigationBarTitle(Text("Detail"))  
      
  

重现步骤:

    使用 SwiftUI 和 Core Data 创建一个新的 Master Detail App 项目。

    在 ContentView 中,将 body 设置为 TabView,第一个选项卡是预构建的 NavigationView,然后添加第二个任意选项卡。

struct ContentView: View   
    @Environment(\.managedObjectContext)  
    var viewContext     

    var body: some View   
        TabView   
            NavigationView   
                MasterView()  
                    .navigationBarTitle(Text("Master"))  
                    .navigationBarItems(  
                        leading: EditButton(),  
                        trailing: Button(  
                            action:   
                                withAnimation  Event.create(in: self.viewContext)   
                          
                        )   
                            Image(systemName: "plus")  
                          
                )  
                Text("Detail view content goes here")  
                    .navigationBarTitle(Text("Detail"))  
              
            .navigationViewStyle(DoubleColumnNavigationViewStyle())  
            .tabItem  Text("Main")   

            Text("Other Tab")  
                .tabItem  Text("Other Tab")   
          
      
  
    添加一些项目。以任何方式与这些项目互动。 更改标签。 改回主选项卡。 尝试删除项目。

【问题讨论】:

【参考方案1】:

我找到了一个纯 SwiftUI 工作解决方案:

/// This View that init the content view when selection match tag.
struct SyncView<Content: View>: View 

    @Binding var selection: Int

    var tag: Int

    var content: () -> Content

    @ViewBuilder
    var body: some View 
        if selection == tag 
            content()
         else 
            Spacer()
        
    

你可以这样使用它:

struct ContentView: View   
    @State private var selection = 0  

    var body: some View   
        TabView(selection: $selection)   

            SyncView(selection: $selection, tag: 0)   
                ViewThatNeedsRefresh()  
              
            .tabItem  Text("First")   
            .tag(0)  

            Text("Second View")  
                .font(.title)  
                .tabItem  Text("Second")   
                .tag(1)  
          
      
  

您可以为每个需要刷新的视图使用 SyncView。

【讨论】:

以上是关于从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新的主要内容,如果未能解决你的问题,请参考以下文章

更新核心数据对象顺序 - 不工作

如何从 SwiftUI 的详细信息视图(编辑项目视图)中删除核心数据条目?

如何从数据数组中删除对象(核心数据)

添加新项目后 UITableView 未更新(使用核心数据)

使用谓词对核心数据进行排序以消除重复

删除子视图中的核心数据后更新表视图