Search code examples
swiftuixcode14

SwiftUI: Trying to figure out NavigationView “Preview Crashed”


Just to note, I’m using NavigationView as I’m targeting iOS 15.

The following code crashes the preview as soon as I click on a link. However, this code compiles ok and also runs ok on the simulator.

Can anyone help me out on why this is causing the preview to crash?

Is my error with navigation or environment?

My MRE is as follows:

@main:

@main
struct Spelling_HiveApp: App {
    @StateObject private var itemData = ItemData()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(itemData)
        }
    }
}

My ContentView is:

struct ContentView: View {
    @EnvironmentObject var itemData: ItemData
    @State private var isShowingPageOne = false
    var body: some View {
        NavigationView {
            HStack {
                NavigationLink(destination: PageOne(), isActive: $isShowingPageOne) { EmptyView() }
                Button("Page One") {
                    self.isShowingPageOne = true
                }
            }
            .navigationTitle("Home")
            .navigationBarTitleDisplayMode(.inline)
        }
        .environmentObject(itemData)
    }
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
    NavigationView {
        ContentView()
            .environmentObject(ItemData())
        }
    }
}

And subsequent structs are as follows (I have left out the PreviewProvider but I am passing .environmentObject(ItemData())):

struct PageOne: View {
    @EnvironmentObject var itemData: ItemData
    var body: some View {
        Form {
            NavigationLink(destination: PageTwo()) {
                Text("Page Two")
            }
        }
        .navigationTitle("Page One")
        .environmentObject(itemData)
    }
}
struct PageTwo: View {
    @EnvironmentObject var itemData: ItemData
    var body: some View {
        Form {
            NavigationLink(destination: Text("Page Three")) {
                Text("Page Three")
            }
        }
        .navigationTitle("Page Two")
        .environmentObject(itemData)
    }
}

And just so this is complete, my model is:

struct Item: Identifiable, Codable {
    var id: Int
    var value: String
    init(id: Int, value: String) {
        self.id = id
        self.value = value
    }
}
extension Item {
    static let sampleData: [Item] =
    [
        Item(id: 1, value: "A"),
        Item(id: 2, value: "B")
    ]
}
class ItemData: ObservableObject {
    @Published var items: [Item] = (Item.sampleData)
}

Any help will be greatly appreciated, thanks!


Solution

  • Your preview is crashing because of an extra NavigationView in your preview, you don't need it. Your ContentView already has NavigationView.

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

    Note:- One more thing you have added ItemData as EnvironmentObject in ContentView, so now no need to pass the same object to each View you are pushing in the navigation stack they all directly have an instance of ItemData as EnvironmentObject. You can remove line .environmentObject(itemData) from your ContentView, PageOne and PageTwo views.