Form NavigationLink issue

Hi,

Sorry for the long post but I have an issue with SwiftUI that is driving me crazy.

Let's take this example view:
Code Block
struct TestNumberPicker: View {
@State private var number = UserDefaults.standard.integer(forKey: "number")
var body: some View {
VStack {
Stepper("Number", value: $number, in: 0...240, step: 5)
Text("Selected number: \(number)")
}
.onChange(of: number, perform: { newNumber in
UserDefaults.standard.setValue(newNumber, forKey: "number")
})
}
}

The view has a state variable named "number" initialized with a value readed from the UserDefaults. This variable is linked to a Stepper. When the value of "number" is changed a block is executed to save the new value in the UserDefaults.

Now, this works correctly if for example this view is presented modally but it doesn't work anymore if the view is presented via a NavigationLink, like this:

Code Block
struct TestForm: View {
var body: some View {
NavigationView {
Form {
NavigationLink("Pick a number", destination: TestNumberPicker())
}
.navigationBarTitle(Text("Test"), displayMode: .inline)
}
}
}

The first time the view is displayed everything work as expected but if I tap on back and I select again the NavigationLink something weird appends. The "number" variable is reset to the original value.

This is an example:
  • I tap on the navigation item.

  • The view is displayed.

  • The "number" variable is initialised with 10 (read from the UserDefaults).

  • I tap once on the stepper (+).

  • The "number" variable become 15.

  • The view is displaying "Selected number: 15"

  • The UserDefaults save 15 (confirmed by reading the plist file).

  • I tab on back.

  • I tap again on the NavigationItem.

  • The view is displayed but the "number" variable contain 10 instead of 15!

I believe the problem has to do with NavigationLink not lazy loading the view. In fact if I forces the view to load lazy:
Code Block
struct TestForm: View {
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
var body: some View {
NavigationView {
Form {
NavigationLink("Pick a number", destination: LazyView(TestNumberPicker()))
}
.navigationBarTitle(Text("Test"), displayMode: .inline)
}
}

then everything work as expected.

What is exactly the problem?
It is something I'm doing wrong?

Thank you


Form NavigationLink issue
 
 
Q