如何创建一个全局发行商?



我尝试做一个全球性的出版商,比如:

@Published var counter = 0

但是这里有一个错误:

Property wrappers are not yet supported in top-level code

如何在模型之间共享全局Publisher变量?

如果你想要一个全局变量以类似于@Published属性的方式发布一个值,你可以这样做

var counter = CurrentValueSubject<Int,Never>(0)
let subscription = counter.sink { print("The counter is ($0)") }
counter1.value = 3

但是如果你正在使用SwiftUI,那么正如Joakim Danielson在评论中指出的那样,你应该考虑使值成为环境的一部分,而不是全局的。

这个解决方案看起来像:

private struct EnvironmentCounter: EnvironmentKey {
typealias Value = Int
static var defaultValue: Int = 0
static let farReachingCounter: String = "Far Reaching Counter"
}
extension EnvironmentValues {
var farReachingCounter: Int {
get { self[EnvironmentCounter.self] }
set { self[EnvironmentCounter.self] = newValue }
}
}
struct LeafView : View {
@Environment(.farReachingCounter) var counter : Int
var body: some View {
Text("The counter is (counter)")
}
}
struct IntermediateView : View {
var body: some View {
LeafView()
}
}
struct TopLevelView: View {
@State var counter = 0
var body: some View {
VStack {
IntermediateView()
HStack {
Button(action: { counter = counter + 1 }) {
Text("Increment")
}
Button(action: { counter = counter - 1 }) {
Text("Decrement")
}
}
}.environment(.farReachingCounter, counter)
}
}
PlaygroundSupport.PlaygroundPage.current.liveView = UIHostingController(rootView: TopLevelView())

这段代码声明了一个EnvironmentKey,视图可以使用它从环境中提取值。在本例中,键为farReachingCounter

然后在EnvironmentValues上声明一个扩展,该扩展在环境中获取和设置值,并从环境中获取值。

最后我展示了一个SwiftUI层次结构,其中TopLevelView定义了整个层次结构的计数器值。有一个IntermediateView根本不引用法院计数器(它只是在那里显示计数器通过环境向下传递视图层次结构)。然后LeafView显示了如何从环境中提取自定义值。

farReachingCounter对整个模块来说不是全局的,但它是TopLevelView以下的SwiftUI环境的一部分。

解决方案如下:

class Counter: ObservableObject {
@Published var counter = 0

static var shared = Counter.init()

private init() { //Just to hide the method

}
}

相关内容

  • 没有找到相关文章

最新更新