首页 > 解决方案 > 如何在 SwiftUI 中声明“全局 @State 变量”?

问题描述

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

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

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

标签: swiftswiftui

解决方案


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

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

@EnvironmentObject private var userSettings: UserSettings

例子

环境对象:

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))
        }
    }
}

意见:

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)
    }
}

结果:

结果


有关使用环境对象的完整演示,请在此处查看我的答案以及相关的 repo。


推荐阅读