SwiftUI dismiss() does not work on preview

Viewed 60

I am making a TODO app on Xcode (ver 13.4) on mac.

When TodoEditor's "Add" button is tapped, the preview screen should show a ContentView and the ContentView should show updated Todo contents but it shows the ContentView and the updated Todo contents are not in it, then just it stops.

If I use simulator, it works perfectly. So the problem happens only on Xcode' preview screen.

If I delete data.todos.append(newTodo) from TodoEditor.swift, dismiss() works, the preview shows a ContentView and the preview does not stops. Of course todo content is not updated.

What can I do for this?

My source codes are followed. Thank you.

MyApp.swift

import SwiftUI

@main
struct MyApp: App {
    @StateObject var data = Todo()
    
    var body: some Scene {
        WindowGroup {
            NavigationView{
                ContentView()
                    .navigationTitle("My Todo")
            }.environmentObject(data)
            
        }
    }
}

ContentView.swift

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var data: Todo
    var body: some View {
        List{
            ForEach(data.todos){todo in
                NavigationLink{
                    VStack{
                        Text(todo.taskContent)
                    }
                }label: {
                    HStack{
                        Text(todo.taskContent)
                        Text(todo.isCompleted ? "done" : "not yet")
                    }
                }
            }
        }.toolbar{
            ToolbarItem{
                NavigationLink("Add"){
                    TodoEditor()
                        .navigationTitle("Add Todo")
                }
            }
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView{
            ContentView()
                .environmentObject(Todo())
        }
        
    }
}

TodoEditor.swift

import SwiftUI

struct TodoEditor: View {
    @State var newTodo:Task = Task(taskContent: "", isCompleted: false)
    @EnvironmentObject var data:Todo
    @Environment(\.dismiss) var dismiss
    var body: some View {
        VStack{
            Form{
                Section("Task Content"){
                    TextField("Task Content",text: $newTodo.taskContent)
                }
                Section("Complete?"){
                    Toggle("Complete?",isOn: $newTodo.isCompleted)
                }
            }
        }.toolbar{
            ToolbarItem{
               Button("Add"){
                   data.todos.append(newTodo) //<- New todo is added here
                   dismiss() //<- Here is dismiss()
                }
            }
        }
    }
}

struct TodoEditor_Previews: PreviewProvider {
    @Environment(\.dismiss) var dismiss
    static var previews: some View {
        NavigationView{
            TodoEditor(newTodo: Task(taskContent: "Hello", isCompleted:false))
                .environmentObject(Todo())
            
        }
    }
}

Todo.swift

import SwiftUI

class Todo: ObservableObject{
    @Published var todos:[Task] = []
}

struct Task: Identifiable{
    var taskContent: String
    var isCompleted: Bool
    
    var id = UUID()
    
}
0 Answers
Related