I encountered this situation when trying to replace my NavigationStack (iOS 16+) by a NavigationView (for backward compatibility reasons). What I hoped for would be that NavigationStack and NavigationView would have similar behavior since Swift UI is built around State management.
Here is the meat and potatoes of this problem :
@State var examens:[Examen] = []
//...
if #available(iOS 16, *) { // Everything works well
NavigationStack {
ExamenListView(exams: examens)
.task {
xml = await dbFinder(file: "find_cr", ip: ip)
examens = await XML_to_examens(xml: xml)
}
}
} else {
NavigationView {
ExamenListView(exams:examens) // This view isn't rebuilt once the state changes
}
.navigationViewStyle(.stack) // Tried with and without
.task {
xml = await dbFinder(file: "find_cr", ip: ip)
examens = await XML_to_examens(xml: xml)
print(self.examens) // Show that examens has been updated, the call was succesful
}
}
At first I tried re-reading documentations about navigation in swift UI, among thoses, I found this article (https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types) but it still imply that NavigationView and Stack seem to be used the same way.
Then I tried butchering my views to narrow down the problem, trying to put the NavigationView in the ExamenListView, putting print statement here and there, but still without success.
Then, I moved the .task block here and there, but still no success. Putting it as a examenListView modifier in the NavView does nothing, same if I put it straight in the ExamenListView.swift
Then, I tried using the .id modifier to force update my view (It was an idea from people on the Swift Discord) Still no changes.
Here is my examenListView (I didn't conform for Identifiable yet, my source has multiples object with an 0 as id. But even then, the NavStack works wonders) :
struct ExamenListView: View {
let exams: [Examen]
var body: some View {
Section {
List {
ForEach(exams, id: \.self) { exam in
NavigationLink(destination: ExamenDetailView(examen:exam)) {
ExamenView(examen:exam)
}
}
}
} header: {
Text("Exam List")
.font(.title)
}
}
}