I am new to SwiftUI and currently building my first app. However, I am having an issue.
I am programming a multi-view app, in which I would like to use kind of global variables to be able to access and edit them from all my views. For example, I ask the user his "sex", "weight" and "license" at app launch. But, I would also like him to be able to change his details in the "settings" category (being a different view). At the same time, I would like to use the same variables in both the views and make them update in both views. Like basic global variables. Is there a way to do so ?
I have watched an outdated video about @State, @ObservableObject, and @EnvironmentObject. Spoiler alert: I didn't understand. I hope you'll be able to help me. If you need any detail, feel free :) Sam
What I would recommend: an ObservableObject called UserSettings. You can then inject this into the whole app from in your app scene or where the @main is with .environmentObject(UserSettings(...)).
For views which need access to the instance of UserSettings, you would do the following:
@EnvironmentObject private var userSettings: UserSettings
Environment object:
class UserSettings: ObservableObject {
enum Sex: String {
case male
case female
case other
}
@Published var sex: Sex
@Published var weight: Double
@Published var license: Bool
init(sex: Sex, weight: Double, license: Bool) {
self.sex = sex
self.weight = weight
self.license = license
}
}
@main
struct WhateverThisIsApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(UserSettings(sex: .male, weight: 100, license: true))
}
}
}
Views:
struct ContentView: View {
@EnvironmentObject private var userSettings: UserSettings
var body: some View {
VStack {
Text("Current settings:")
Text("Sex: \(userSettings.sex.rawValue)")
Text("Weight: \(userSettings.weight)")
Text("License: \(userSettings.license ? "yes" : "no")")
SomeChildView()
}
}
}
struct SomeChildView: View {
@EnvironmentObject private var userSettings: UserSettings
var body: some View {
Picker("Sex", selection: $userSettings.sex) {
Text("Male").tag(UserSettings.Sex.male)
Text("Female").tag(UserSettings.Sex.female)
Text("Other").tag(UserSettings.Sex.other)
}
.pickerStyle(.segmented)
}
}
Result:

For a full demo of using environment objects, see my answer here along with the associated repo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With