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

问题描述 投票:2回答:2

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

struct Login: View {

    @State static var errorMessage = ""

    init() {
        // ...
    }

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

}

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

问题是,即使是静态的,也总是在每次显示登录视图时重新启动,因此错误消息始终为空。我以为init()方法的存在可能以某种方式启动了它,但是我没有弄清楚如何解决这个问题。我该怎么办?

swift struct static swiftui
2个回答
1
投票

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

相反,静态变量不会在实例之间改变。

这两个概念不兼容。您不应该将static@State一起使用。


0
投票

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

这是@State的误解。 @State变量的重点是管理视图的internal状态。如果某个外部变量甚至正在查看@State变量,更不用说尝试对其进行设置了,那是错误的。

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

class ErrorManager: ObservableObject {
    @Published var errorMessage: String = "xyz"
}

这是管理错误消息的全局对象。任何人都可以呼叫errorManager.errorMessage = "something"进行设置。如果需要,您当然可以通过添加属性来使其成为共享实例:

 static let shared = ErrorManager()

然后,将其传递给视图:

struct Login: View {
    @ObservedObject var errorManager: ErrorManager

    var body: some View {
        Text(errorManager.errorMessage)
    }
}

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

    @ObservedObject var errorManager = ErrorManager.shared

就是这样。现在更改为错误会自动传播。您更可能希望LoginManager或类似的内容来处理整个登录过程,然后观察一下,但过程相同。

© www.soinside.com 2019 - 2024. All rights reserved.