如何在 SwiftUI 中声明“全局@State变量”?

Sam*_*Sam 12 swift swiftui

我是 SwiftUI 新手,目前正在构建我的第一个应用程序。但是,我有一个问题。

我正在编写一个多视图应用程序,在其中我想使用某种全局变量以便能够从我的所有视图访问和编辑它们。例如,我在应用启动时询问用户的“性别”、“体重”和“许可证”。但是,我也希望他能够在“设置”类别中更改他的详细信息(作为不同的视图)。同时,我想在两个视图中使用相同的变量,并使它们在两个视图中更新。就像基本的全局变量一样。有办法这样做吗?

我看过一个关于 @State、@ObservableObject 和 @EnvironmentObject 的过时视频。剧透警告:我没听懂。我希望你能帮助我。如果您需要任何详细信息,请随意:) Sam

Geo*_*e_E 21

我会推荐什么:一个ObservableObject叫做UserSettings. 然后,您可以从应用程序场景或 @main 所在的位置将其注入到整个应用程序中.environmentObject(UserSettings(...))

对于需要访问 实例的视图UserSettings,您将执行以下操作:

@EnvironmentObject private var userSettings: UserSettings
Run Code Online (Sandbox Code Playgroud)

例子

环境对象:

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
    }
}
Run Code Online (Sandbox Code Playgroud)
@main
struct WhateverThisIsApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(UserSettings(sex: .male, weight: 100, license: true))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

浏览次数:

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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
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)
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

结果


有关使用环境对象的完整演示,请参阅此处我的答案以及相关的存储库。