SwiftUI TabView со списком, не обновляющимся после того, как возражение было удалено из / добавлено в базовые данные - PullRequest
0 голосов
/ 26 марта 2020

Описание:

Когда объект в списке (созданный из выборочного запроса) удаляется из контекста и контекст сохраняется, список не обновляется должным образом.

Ошибка:

Поток 1: фатальная ошибка: неожиданно обнаружен ноль при развертывании необязательного значения (добавлено в строку 5 ниже)

struct DetailView: View {  
    @ObservedObject var event: Event  

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

Действия для воспроизведения:

  1. Создание нового проекта приложения Master Detail с SwiftUI и базовыми данными.

  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 Ответ

1 голос
/ 26 марта 2020

Я нашел чистое рабочее решение 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 для каждого представления, которое нуждается в обновлении. sh.

...