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

时间:2020-03-26 01:46:53

标签: swift generics core-data swiftui

说明:

从上下文中删除列表(通过fetchrequest创建)中的对象并保存该上下文时,列表无法正确更新。

错误:

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

struct DetailView: View {  
    @ObservedObject var event: Event  

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

复制步骤:

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

  2. 在ContentView中,将主体设置为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. 添加一些项目。以任何方式与这些物品进行互动。
  2. 更改标签。
  3. 回到主标签。
  4. 试图删除一个项目。

1 个答案:

答案 0 :(得分: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。