我考虑有什么区别
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/xxx/TestApp.app> (loaded)' with name 'MyViewController''
我知道首先可以直接在SwiftUI View中使用它,即使用$符号创建绑定,然后例如使用@Published var isLoggedIn: Bool = false
var isLoggedIn: AnyPublisher<Bool, Never>
但是如何使用if $isLoggedIn.animation()
达到相同的效果,看来我需要在某个地方调用分配或接收器和 store()< / strong>。使它工作。因此,像AnyPublisher<Bool, Never>
@Published的局限性是我无法进行自定义观察。例如,我可以通过UserDefaults.publisher中的AnyPublisher进行操作。
现在看来我需要同时拥有if $isLoggedIn.animation
和更新AnyPublisher
但是我一直认为@Published是常规的AnyPublisher之下的属性包装器,所以为什么不能直接从AnyPublisher在SwiftUI视图中进行绑定?
答案 0 :(得分:4)
Combine的@Published
是由属性包装器包装的发布者。这为它提供了$
前缀的属性以及SwiftUI赖以工作的其他功能。
@Published
属性也根本不像AnyPublisher
。 @Published
始终以Never
作为其失败类型,AnyPublisher
可以有其他失败案例。
@Published
具有状态感/当前值,AnyPublisher
则不然。 CurrentValueSubject
会最接近,但不会起作用,因为@Published
可用作CurrentValueSubject
不可能的绑定。一个重要的区别是SwiftUI可以直接为@Published
属性分配新值(isLoggedIn = true
会在此处触发更改)。
要在SwiftUI中与发布商合作,您需要将其值分配给您在原始问题中提到的专用@Published
属性。
答案 1 :(得分:0)
自定义观察的示例用法
import SwiftUI
import Combine
class Model: ObservableObject {
@Published var flag = false
}
struct ContentView: View {
@ObservedObject var model: Model
let handle: AnyCancellable?
init() {
let m = Model()
handle = m.$flag.sink(receiveValue: { (b) in
print("model flag changed to:", b)
})
model = m
}
var body: some View {
Toggle(isOn: $model.flag) {
Text("Toggle")
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
来自SwiftUI。查看发布者的方式为
$model.$flag
如果需要。