I am passing a Person
binding
from the first view to the second view to the third view, when I update the binding
value in the third view it pops back to the second view, I understand that SwiftUI updates the views that depend on the state value, but is poping the current view is the expected behavior or I am doing something wrong?
struct Person: Identifiable {
let id = UUID()
var name: String
var numbers = [1, 2]
}
struct FirstView: View {
@State private var people = [Person(name: "Current Name")]
var body: some View {
NavigationView {
List($people) { $person in
NavigationLink(destination: SecondView(person: $person)) {
Text(person.name)
}
}
}
}
}
struct SecondView: View {
@Binding var person: Person
var body: some View {
Form {
NavigationLink(destination: ThirdView(person: $person)) {
Text("Update Info")
}
}
}
}
struct ThirdView: View {
@Binding var person: Person
var body: some View {
Form {
Button(action: {
person.numbers.append(3)
}) {
Text("Append a new number")
}
}
}
}
2
Answers
SwiftUI works by updating the rendered views to match what you have in your state.
In this case, you first have a list that contains an element called
Current Name
. Using aNavigationLink
you select this item.You update the name and now that previous element no longer exists, it’s been replaced by a new element called
New Name
.Since
Current Name
no longer exists, it also cannot be selected any longer, and the view pops back to the list.To be able to edit the name without popping back, you’ll need to make sure that the item on the list is the same, even if the name has changed. You can do this by using an
Identifiable
struct
instead of aString
.When navigating twice you need to either use
isDetailLink(false)
orStackNavigationViewStyle
, e.g.