我有一个看起来像这样的视图:
struct Login: View {
@State static var errorMessage = ""
init() {
// ...
}
var body: some View {
// ...
}
}
我将errorMessage
设置为静态,所以我可以从任何地方设置错误消息。
问题是,即使是静态的,也总是在每次显示登录视图时重新启动,因此错误消息始终为空。我以为init()方法的存在可能以某种方式启动了它,但是我没有弄清楚如何解决这个问题。我该怎么办?
@State
创建与视图的实例关联的有状态容器。视图的每个实例都有该@State
容器的副本。
相反,静态变量不会在实例之间改变。
这两个概念不兼容。您不应该将static
与@State
一起使用。
我将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
或类似的内容来处理整个登录过程,然后观察一下,但过程相同。