我们如何从 SwiftUI 中的其他结构中读取 @State 变量?
Posted
技术标签:
【中文标题】我们如何从 SwiftUI 中的其他结构中读取 @State 变量?【英文标题】:How we can read @State variable from other struct in SwiftUI? 【发布时间】:2020-10-28 15:24:16 【问题描述】:我想知道是否有简单或正确的方法从不同的视图读取状态变量值,我知道 .onChange 或 Binding 或 ObservableObject(class) 的用法和...,但我想知道的是还有其他更好的方法吗?
例如,在这段代码中,我有一个名为 TextView 的视图,它有一个状态值,我在我的 ContentView 中调用这个视图,现在我在我的 ContentView 中放置一个文本,我想读取 TextView 的状态值。这项工作有空间方法吗?
struct ContentView: View
@State var readStringOfTextView: String = ""
var body: some View
TextView()
Text(readStringOfTextView)
.foregroundColor(Color.blue)
struct TextView: View
@State var stringOfText: String = "Hello, world!"
var body: some View
Text(stringOfText)
.padding()
.foregroundColor(Color.red)
【问题讨论】:
【参考方案1】:State 的全部意义在于它在 View 的内部。如果您尝试在其他地方阅读它,那么您的设计中出现了问题。在这种情况下,您需要的工具是 @Binding
。 ContentView 应该将 Binding 传递给 TextView。 ContentView 将看到 TextView 中的任何更改(在您的示例中,这没有意义,因为stringOfText
无法更改,但我假设您的其余代码会以某种方式更改它)。在您的示例中,这看起来像这样:
struct ContentView: View
@State var readStringOfTextView: String = ""
var body: some View
TextView(stringOfText: $readStringOfTextView)
Text(readStringOfTextView)
.foregroundColor(Color.blue)
struct TextView: View
@Binding var stringOfText : String
var body: some View
Text(stringOfText)
.padding()
.foregroundColor(Color.red)
.onAppear
stringOfText = "Hello, world!"
可以使用首选项直接将数据向上传递到视图层次结构,但它要复杂得多,而且不是解决您所描述问题的正确工具。即便如此,它是这样的:
创建一个 PreferenceKey 来传递数据 使用.preference
在子视图中设置 PreferenceKey
使用.onPreferenceChange
或.overlayPreferenceValue
或.backgroundPreferenceValue
读取父视图中的PreferenceKey。
struct TextPreference: PreferenceKey
static var defaultValue = "default"
static func reduce(value: inout String, nextValue: () -> String)
value = nextValue()
struct ContentView: View
@State var readStringOfTextView: String = ""
var body: some View
VStack
TextView()
.onPreferenceChange(TextPreference.self) value in
readStringOfTextView = value
Text(readStringOfTextView)
.foregroundColor(Color.blue)
struct TextView: View
@State var stringOfText : String = "Hello, world!"
var body: some View
Text(stringOfText)
.padding()
.foregroundColor(Color.red)
.preference(key: TextPreference.self, value: stringOfText)
【讨论】:
正如我所说,我已经知道 State 和 Binding 的用法,. . . TextView 是没有观察到的东西!你把绑定放在那里!请看我的代码。我想阅读 TextView 的状态,也许更接近和更合乎逻辑的方式是 ObservableObject 在 TextView 和 ContentView 之间共享,有人可以读或写,我正在寻找更好的方法 是的,如果您有状态希望多个视图都观察和共享,ObservableObject 将是正确的工具。您不得阅读其他视图状态。状态是明确的内部的。首选项也适用于此,但通常不是您所描述的那种东西的正确工具。如果它是“类似模型的”,那么您需要一个 Observable。 所以,这就是我问这个问题的原因,我不确定是否有比 ObservableObject 方法更好的方法!当我要使用 ObservableObject 时,我正在做颠倒的工程来解决这个问题,在这种情况下,我使用的不是 State 而是 StateObject,所以说 State 不能从外部访问,但 StateObject 是正确的! !我可以说最好和正确的答案是 StateObject 吗? StateObject 为 View 提供了一些原本是 ObservedObject 的东西的所有权。这很方便,因为这意味着在***视图中,您不需要传入对象。但您仍然不能尝试询问子视图的 StateObjects。 “状态”的东西总是私有的。视图永远不是更高级别视图(或系统的其他部分)状态的所有者。 WWDC20:developer.apple.com/videos/play/wwdc2020/10040以上是关于我们如何从 SwiftUI 中的其他结构中读取 @State 变量?的主要内容,如果未能解决你的问题,请参考以下文章
将数据从委托 Swift 类传递到 SwiftUI 结构中的 EnvironmentObject