1

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()
    
}
peridotite
  • 115
  • 3
  • you could try removing all those `NavigationView` from your `Previews`. – workingdog support Ukraine Sep 09 '22 at 23:09
  • @workingdogsupportUkraine Once I remove NavigationView form Previews of ContentView_Previews, the preview won't work. – peridotite Sep 10 '22 at 09:42
  • When I add an item to tap the "Add" button, It stops working. So sharing data between views could be a problem. – peridotite Sep 10 '22 at 09:45
  • In `ContentView`, could you try replacing the `NavigationLink("Add"){...}`, with `NavigationLink("Add", destination: TodoEditor()).navigationTitle("Add Todo")`, seems to work for me. – workingdog support Ukraine Sep 10 '22 at 11:01
  • 1
    Note, it would be best to rename your `Task` struct, because Swift already has a `Task` struct, and it may confuse the compiler and yourself later on. – workingdog support Ukraine Sep 10 '22 at 11:11
  • @workingdogsupportUkraine Thank you for your advise. I replaced the name Task and also NavigationLink you pointed but the preview stopped and problem report screen popped up. It works on simulator but not on Xcode preview... – peridotite Sep 10 '22 at 17:50
  • 1
    Note, you Previews (`TodoEditor_Previews` and `ContentView_Previews`) have different `Todo()`. In other words they are not connected to each other, they are not "sharing" data as you call it. – workingdog support Ukraine Sep 11 '22 at 02:55
  • @workingdogsupportUkraine Really? Can't they have same data? That's an answer... Would you mind showing me how to replace them? – peridotite Sep 11 '22 at 04:53
  • Xcode `Previews` are for displaying the UI code and its visual representation side by side, without rebuilding the project. To really simulate your App, use a simulator or better still, a real device. Do not use the `Previews` to simulate your App, they are not full simulators. – workingdog support Ukraine Sep 11 '22 at 05:44

0 Answers0