如何从SwiftUI中的其他结构读取@State变量?

如何从SwiftUI中的其他结构读取@State变量?,swiftui,Swiftui,我想知道是否有简单或正确的方法从不同的视图读取状态变量值,我知道.onChange、Binding或observeObjectClass和…,但我想知道还有其他更好的方法吗 例如,在这段代码中,我有一个名为TextView的视图,它有一个状态值,我在ContentView中调用这个视图,现在我在ContentView中放了一个文本,我想读取TextView的状态值。这项工作有专门的方法吗 struct ContentView: View { @State var readStringOf

我想知道是否有简单或正确的方法从不同的视图读取状态变量值,我知道.onChange、Binding或observeObjectClass和…,但我想知道还有其他更好的方法吗

例如,在这段代码中,我有一个名为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)
    }
}

状态的整体观点是它是视图的内部。如果您试图在其他地方阅读,则说明您的设计出现了问题。在本例中,您需要的工具是@Binding。ContentView应向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。 结构文本首选项:首选项键{ 静态var defaultValue=default 静态函数reducevalue:inout字符串,nextValue:->String{ 值=下一个值 } } 结构ContentView:View{ @状态变量readStringOfTextView:字符串= var body:一些观点{ VStack{ 文本框 .onPreferenceChangeTextPreference.self{中的值 readStringOfTextView=值 } TextreadStringOfTextView .foregroundColorColor.blue } } } 结构文本视图:视图{ @State var stringOfText:String=Hello,world! var body:一些观点{ 文本字符串 衬料 .foregroundColorColor.red .preferencekey:TextPreference.self,值:stringOfText } }
状态的整体观点是它是视图的内部。如果您试图在其他地方阅读,则说明您的设计出现了问题。在本例中,您需要的工具是@Binding。ContentView应向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。 结构文本首选项:首选项键{ 静态var defaultValue=default 静态函数reducevalue:inout字符串,nextValue:->String{ 值=下一个值 } } 结构ContentView:View{ @状态变量readStringOfTextView:字符串= var body:一些观点{ VStack{ 文本框 .onPreferenceChangeTextPreference.self{中的值 readStringOfTextView=值 } TextreadStringOfTextView .foregroundColorColor.blue } } } 结构文本视图:视图{ @State var stringOfText:String=Hello,world! var body:一些观点{ 文本字符串 衬料 .foregroundColorColor.red .preferencekey:TextPreference.self,值:stringOfText } }
正如我所说,我已经知道状态和绑定的用法。TextView不是在观察什么!你把它放在那儿了!请看我的密码。我想阅读TextView的状态,也许更接近和更合理的方式是ObservieObject在TextView和ContentView之间共享,有人可以读或写,我想找到更好的方式是的,ObservieObject将是正确的工具,如果你有状态,你希望多个视图都可以观察和共享。您不能读取其他状态视图。状态是显式内部的。首选项也适用于此,但通常不是您所描述的类型的正确工具。如果是这样的模型,那么你需要一个可观察的。所以,这就是为什么我问这个问题,我不确定是否有比ObservieObject方法更好的方法!当我打算使用ObserveObject时,我正在做倒置的工程来解决这个问题,在这种情况下,我使用的不是状态,而是状态
对象,所以说状态不能从外部访问,但StateObject是!?!我能说最好的正确答案是StateObject吗?StateObject提供了一个视图,它拥有一个原本可以被观察到的对象的所有权。这很方便,因为这意味着在顶级视图中,不需要传入对象。但是您仍然不能尝试询问子视图的StateObjects。国家事务总是私人的。视图永远不是更高级别视图或系统其他部分的状态所有者。关于它如何工作的最好概述来自WWDC20:正如我所说,我已经知道状态和绑定的用法。TextView不是在观察什么!你把它放在那儿了!请看我的密码。我想阅读TextView的状态,也许更接近和更合理的方式是ObservieObject在TextView和ContentView之间共享,有人可以读或写,我想找到更好的方式是的,ObservieObject将是正确的工具,如果你有状态,你希望多个视图都可以观察和共享。您不能读取其他状态视图。状态是显式内部的。首选项也适用于此,但通常不是您所描述的类型的正确工具。如果是这样的模型,那么你需要一个可观察的。所以,这就是为什么我问这个问题,我不确定是否有比ObservieObject方法更好的方法!当我要使用ObserveObject时,我正在做倒置的工程来解决这个问题,在这种情况下,我使用的不是State而是StateObject,所以说State不能从外部访问,但是StateObject是!?!我能说最好的正确答案是StateObject吗?StateObject提供了一个视图,它拥有一个原本可以被观察到的对象的所有权。这很方便,因为这意味着在顶级视图中,不需要传入对象。但是您仍然不能尝试询问子视图的StateObjects。国家事务总是私人的。视图永远不是更高级别视图或系统其他部分的状态所有者。关于这一工作原理的最佳概述来自WWDC20: