@State 静态属性正在重新启动,恕不另行通知

Cin*_*inn 3 static struct swift swiftui

我有一个看起来像这样的视图:

struct Login: View {

    @State static var errorMessage = ""

    init() {
        // ...
    }

    var body: some View {
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

我设置errorMessage为静态,这样我就可以从任何地方设置错误消息。

问题是,即使是静态的,每次显示登录视图时它总是会重新启动,因此错误消息总是为空。我在想,也许 init() 方法的存在会以某种方式启动它,但我不知道如何解决这个问题。我能做些什么?

Rob*_*ier 9

我将 errorMessage 设置为静态,这样我就可以从任何地方设置错误消息。

这是对@State的误解。@State 变量的目的是管理视图的内部状态。如果外部的东西甚至在查看 @State 变量,更不用说尝试设置它了,那就是出了问题。

相反,您需要的是传递给视图(或作为共享实例访问)的 @ObservableObject。例如:

class ErrorManager: ObservableObject {
    @Published var errorMessage: String = "xyz"
}
Run Code Online (Sandbox Code Playgroud)

这是管理错误消息的全局事物。任何人都可以打电话errorManager.errorMessage = "something"来设置。当然,如果您愿意,可以通过添加属性将其设为共享实例:

 static let shared = ErrorManager()
Run Code Online (Sandbox Code Playgroud)

这样,您就可以将其传递给视图:

struct Login: View {
    @ObservedObject var errorManager: ErrorManager

    var body: some View {
        Text(errorManager.errorMessage)
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果需要,您可以使用共享实例:

    @ObservedObject var errorManager = ErrorManager.shared
Run Code Online (Sandbox Code Playgroud)

就是这样。现在更改为错误自动传播。您更有可能需要一个LoginManager或类似的东西来处理整个登录过程,然后观察它,但过程是相同的。


Gil*_*man 5

@State创建与视图实例关联的有状态容器。视图的每个实例都有它自己的该@State容器的副本。

相反,静态变量不会在实例之间发生变化。

这两个概念是不兼容的。您不应该使用staticwith @State