I am having a strange issue with an @State var not updating an iOS SwiftUI view. I have an edit screen for themes for a small game with a NavigationView with a list of game themes. When in edit mode and I select one of these themes, I open up an editor view, passing the theme as a binding to the editor view struct. In my editor view I then have sections that allow the user to edit properties of the theme. I do not want to use bindings to the various theme properties in my edit fields because I do not want the changes to take effect immediately. Instead, I have created @State vars for each of these properties and then use bindings to these in the edit fields. That way, I give the user the option to either cancel without and changes taking effect, or select "Done" to assign the changes back to the theme via the binding. In order to initialise the @State vars I have an onAppear block that assign the @State vars values from the respective theme properties. The issue I am having is that when the onAppear block is executed and the vars are assigned, the relevant edit fields are not updating! Here is a cut-down version of my code:
struct EditorView: View {
/// The current presentation mode of the view.
@Environment(\.presentationMode) var presentationMode
@Binding var theme: GameTheme
@State private var name = ""
...
var body: some View {
NavigationView {
Form {
nameSection
...
}
.navigationTitle("Edit \(theme.name)")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel", action: cancel)
}
ToolbarItem(placement: .confirmationAction) {
Button("Done", action: saveTheme)
.disabled(!canSaveTheme)
}
}
.onAppear {
name = theme.name
...
}
}
.frame(minWidth: Constants.minViewSize.width, minHeight: Constants.minViewSize.height)
}
var nameSection: some View {
Section(header: Text("Name")) {
TextField(LocalizedStringKey("Name"), text: $name)
}
}
...
}
So the view gets shown an on appearing, the @State var name does correctly get assigned the value from theme.name; however, this allocation does not cause an update of the view and the value of "name" is not entered into the TextField.
Interestingly, and I do not know if this is a good thing to do, if I wrap the contents of the onAppear block in a DispatchQueue.main.async, everything works fine!
i.e.
.onAppear {
DispatchQueue.main.async {
name = theme.name
...
}
}
Does anyone have any idea as to how, within the onAppear, I can force a view refresh? Or, why the assignment to "name" does not force an update?
Thanks.

class GameTheme. The@Stateobserves the object as a whole. Meaning that it will only change if it is astructOr something like aString. If you want to observe the variables of aclassyou have to have it conform toObservableObjectand wrap the variables with@Publishedand then use@StateObjectOr@ObservedObjecinit(theme: Binding<GameTheme>)and then within the init assigned the theme via_theme = themeand then assigned the name via_name = State(initialValue: theme.name.wrappedValue).