可以直接使用 Publisher 作为 SwiftUI 中的 @ObjectBinding 属性吗?
Posted
技术标签:
【中文标题】可以直接使用 Publisher 作为 SwiftUI 中的 @ObjectBinding 属性吗?【英文标题】:Can you use a Publisher directly as an @ObjectBinding property in SwiftUI? 【发布时间】:2019-06-22 20:24:37 【问题描述】:在 SwiftUI 中,您可以将 Publisher
的实例直接用作 @ObjectBinding
属性,还是必须将其包装在实现 BindableObject
的类中?
let subject = PassthroughSubject<Void, Never>()
let view = ContentView(data:subject)
struct ContentView : View
@ObjectBinding var data:AnyPublisher<Void, Never>
// When I want to refresh the view, I can just call:
subject.send(())
这不会为我编译,只会挂起 Xcode 11 Beta 2。但你应该被允许这样做吗?
【问题讨论】:
【参考方案1】:在您的视图正文中使用.onReceive
传递发布者,如下例所示,取自Data Flow Through SwiftUI - WWDC 2019 @ 21:23。在闭包内部,您更新了一个 @State 变量,而该变量又在主体中的其他位置被引用,这会导致主体在更改时被调用。
【讨论】:
【参考方案2】:您可以实现一个BindableObject
,它将发布者作为初始化参数。
并使用方便的函数扩展Publisher
以创建此BindableObject
。
class BindableObjectPublisher<PublisherType: Publisher>: BindableObject where PublisherType.Failure == Never
typealias Data = PublisherType.Output
var didChange: PublisherType
var data: Data?
init(didChange: PublisherType)
self.didChange = didChange
_ = didChange.sink (value) in
self.data = value
extension Publisher where Failure == Never
func bindableObject() -> BindableObjectPublisher<Self>
return BindableObjectPublisher(didChange: self)
struct ContentView : View
@ObjectBinding var binding = Publishers.Just("test").bindableObject()
var body: some View
Text(binding.data ?? "Empty")
【讨论】:
感谢您的建议,但是当我提到在类中包装Publisher
时,这正是我希望避免的情况。我希望有一些我忽略的协议或现有 API。
BindableObject
s 必须是一个类。所以这不是要避免的。以上是关于可以直接使用 Publisher 作为 SwiftUI 中的 @ObjectBinding 属性吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Swift Combine 创建一个 Timer Publisher