Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare "global @State variables" in SwiftUI?

Tags:

swift

swiftui

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

like image 814
Sam Avatar asked Jan 25 '26 15:01

Sam


1 Answers

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

Example

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:

Result


For a full demo of using environment objects, see my answer here along with the associated repo.

like image 115
George Avatar answered Jan 27 '26 06:01

George



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!