Post

Replies

Boosts

Views

Activity

@State's initial value doesn't change on re-render
Problem Statement I'm having trouble understanding how to reset a @State property to its initial value. In my app, I have one view that sets an integer "default value". The other view reads it, but doesn't change it: struct ContentView: View {     @State var selectedValue = 1     var body: some View {         VStack{             DefaultValueView(defaultValue: $selectedValue)             ComputeView(defaultValue: selectedValue)         }     } } The first view is simple: it uses a @Binding to the selected value and updates it based on the user's selection. Here, we let the user choose a default value between 1 and 10: struct DefaultValueView: View {     @Binding var defaultValue: Int     var body: some View {         VStack {             Text("Select the default value")             ForEach(1...10, id: \.self) { i in                 Button("Value: \(i)") {                     defaultValue = i                 }.background(i == defaultValue ? Color.red : Color.clear)             }         }     } } In a second, I want to have the following behavior: When the selectedValue changes, it displays the selected value. The user can increment or decrement the displayed value. This doesn't change the selectedValue, just what's displayed in this view. My attempt was this: struct ComputeView: View {     @State var additionalValue: Int          init(defaultValue: Int) {         _additionalValue = State(initialValue: defaultValue)     }          var body: some View {         VStack {             Text("10 plus..")             Stepper("\(additionalValue)") {                 additionalValue += 1             } onDecrement: {                 additionalValue -= 1             }             Text("= \(10 + additionalValue)")         }.padding()     } } This achieves the 2nd behavior (I can edit the displayed value with the stepper) but not the 1st. When I change "default value" to something else, it doesn't change in this view. I've got a breakpoint in the init method, so I know it's being re-set to the new initialValue, but it doesn't change. What am I missing? Full app to copy/paste: import SwiftUI @main struct DefaultEditableValueApp: App {     var body: some Scene {         WindowGroup {             ContentView()         }     } } struct ContentView: View {     @State var selectedValue = 1     var body: some View {         VStack{             DefaultValueView(defaultValue: $selectedValue)             ComputeView(defaultValue: selectedValue)         }     } } struct DefaultValueView: View {     @Binding var defaultValue: Int     var body: some View {         VStack {             Text("Select the default value")             ForEach(1...10, id: \.self) { i in                 Button("Value: \(i)") {                     defaultValue = i                 }.background(i == defaultValue ? Color.red : Color.clear)             }         }     } } struct ComputeView: View {     @State var additionalValue: Int          init(defaultValue: Int) {         _additionalValue = State(initialValue: defaultValue)     }          var body: some View {         VStack {             Text("10 plus..")             Stepper("\(additionalValue)") {                 additionalValue += 1             } onDecrement: {                 additionalValue -= 1             }             Text("= \(10 + additionalValue)")         }.padding()     } }
3
1
4.9k
Aug ’20