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()
}