为什么可以';swiftui能否区分两种不同的环境对象?

为什么可以';swiftui能否区分两种不同的环境对象?,swiftui,Swiftui,我有这段代码,希望有一个b作为文本 结果:a->参见屏幕截图。我做错了什么 import SwiftUI class PublishString : ObservableObject { init(string: String) { self.string = string print(self.string) } @Published var string : String = "a" } struct ContentView:

我有这段代码,希望有一个b作为文本

结果:a->参见屏幕截图。我做错了什么

import SwiftUI

class PublishString : ObservableObject {

    init(string: String) {
        self.string = string
        print(self.string)
    }

    @Published var string : String = "a"
}

struct ContentView: View {

    @EnvironmentObject var text1 : PublishString
    @EnvironmentObject var text2 : PublishString

    var body: some View {
        VStack {
            Text(text1.string)
            Text(text2.string)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(PublishString(string: "a"))
        .environmentObject(PublishString(string: "b"))
    }
}

而且……这是有效的:

class PublishString : ObservableObject {

    init(string: String) {
        self.string = string
        print(self.string)
    }

    @Published var string : String = "a"
}

class PublishString2 : ObservableObject {

    init(string: String) {
        self.string = string
        print(self.string)
    }

    @Published var string : String = "a"
}

struct ContentView: View {

    @EnvironmentObject var text1 : PublishString
    @EnvironmentObject var text2 : PublishString2

    var body: some View {
        VStack {
            Text(text1.string)
            Text(text2.string)
        }
    }
}
如注释中所述,SwiftUI按类型(您使用的类定义)标识环境对象。它查找该类型的对象并使用找到的第一个对象

一个选项是在一个对象上有多个属性,您可以访问这些属性(这意味着在您的情况下有两个独立的
String
属性)

更多信息可在Apple上获得。

如注释中所述,SwiftUI通过类型(您使用的类定义)标识环境对象。它查找该类型的对象并使用找到的第一个对象

一个选项是在一个对象上有多个属性,您可以访问这些属性(这意味着在您的情况下有两个独立的
String
属性)


更多信息可以在苹果上找到。

公认的答案非常准确,回答了这个问题

如果您必须在应用程序中使用两个相同类型的EnvironmentObjects进行传递,并且偶然发现这个问题,那么以下是一个简单的解决方法:

您可以创建第二个类,该类继承第一个类的所有内容。因此,您可以避免冗余,并且可以分别使用两个EnvironmentObjects

class PublishString : ObservableObject {

    init(string: String) {
        self.string = string
        print(self.string)
    }

    @Published var string : String = "a"
}

class PublishString2 : PublishString {}

struct ContentView: View {

    @EnvironmentObject var text1 : PublishString
    @EnvironmentObject var text2 : PublishString2

    var body: some View {
        VStack {
            Text(text1.string)
            Text(text2.string)
        }
    }
}
实例化:

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(PublishString(string: "a"))
        .environmentObject(PublishString2(string: "b"))
    }
}

被接受的答案完全正确,回答了这个问题

如果您必须在应用程序中使用两个相同类型的EnvironmentObjects进行传递,并且偶然发现这个问题,那么以下是一个简单的解决方法:

您可以创建第二个类,该类继承第一个类的所有内容。因此,您可以避免冗余,并且可以分别使用两个EnvironmentObjects

class PublishString : ObservableObject {

    init(string: String) {
        self.string = string
        print(self.string)
    }

    @Published var string : String = "a"
}

class PublishString2 : PublishString {}

struct ContentView: View {

    @EnvironmentObject var text1 : PublishString
    @EnvironmentObject var text2 : PublishString2

    var body: some View {
        VStack {
            Text(text1.string)
            Text(text2.string)
        }
    }
}
实例化:

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(PublishString(string: "a"))
        .environmentObject(PublishString2(string: "b"))
    }
}

因为内部存储是按类型区分的…事实上是你自己发现的。因为内部存储是按类型区分的…事实上是你自己发现的。如果我想重用一个将此类用作environmentobject的组件,那么我不能使用多个实例,如果是的话?@Chris是的,尽管可以使用不同的实例将其转换为祖先视图,以便在应用程序的不同部分中使用。据我所知,这是可以的(前提是没有视图有两个“上游”同一类的环境对象。@Chris我找到了这个答案,它提供了一种类似这样的方法,使用单个对象的两个属性:如果我想重用一个将该类用作环境对象的组件,那么我不能使用多个实例,如果是的话?@Chris是的,尽管可以将不同的实例注入到祖先视图中或者在应用程序的不同部分中使用。据我所知,这是可以的(前提是没有视图具有同一类的两个“上游”环境对象。@Chris我找到了这个答案,它提供了这样一种方法,使用单个对象的两个属性: