1

I'd like to update an UI element on an overview view when data on another view is changed.

I looked into @EnvironmentalObject and @Binding. However, an update to either object does not appear to force a view reload. Only changes to @State force renders.
Also, in the case described below, the ChangeView is not a child of OverviewView. Therefore @Binding is not an option anyway.

Data.swift

struct ExampleData : Hashable { var id: UUID var name: String } var globalVar: ExampleData = ExampleData(id: UUID(), name:"") 

OverviewView.swift

struct OverviewView: View { @State private var data: ExampleData = globalVar var body: some View { Text(data.name) } } 

ChangeView.swift

struct ChangeView: View { @State private var data: ExampleData = globalVar var body: some View { TextField("Name", text: $data.name, onEditingChanged: { _ in globalVar = data }, onCommit: { globalVar = data }) } } 

Changes within the ChangeView TextField will update the globalVar. However, this will not update the Text on the OverviewView when switching back to the view.

I am aware that using global variables is "ugly" coding. How do I handle data that will be used in a multitude of unrelated views?

Please advise on how to better handle such a situation.

1 Answer 1

3

OverviewView and ChangeView hold different copies of the ExampleData struct in their data variables (When assigning a struct to another variable, you're effectively copying it instead of referencing it like an object.) so changing one won't affect the other.

@EnvironmentObject suits your requirements.

Here's an example:
Since, we're using @EnvironmentObject, you need to either convert ExampleData to a class, or use a class to store it. I'll use the latter.

class ExampleDataHolder: ObservableObject { @Published var data: ExampleData = ExampleData(id: UUID(), name:"") } struct CommonAncestorOfTheViews: View { var body: some View { CommonAncestorView() .environmentObject(ExampleDataHolder()) } } struct OverviewView: View { @EnvironmentObject var dataHolder: ExampleDataHolder var body: some View { Text(dataHolder.data.name) } } struct ChangeView: View { @EnvironmentObject var dataHolder: ExampleDataHolder var body: some View { TextField("Name", text: $dataHolder.data.name) } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.