如何解决SwiftUI 接收自定义事件
我有一个 ObservableObject
,它使用 @Published
属性包装器发布一些值。该对象还包含一个计时器。
问题是,如何在计时器执行后立即触发事件并在 SwiftUI 的视图中处理该事件(我更喜欢使用 onReceive
之类的东西)?
已经使用组合框架发布更改值,我想正确实现此事件触发/处理。但到目前为止,我所读到的关于 Combine 的所有内容都是关于处理价值变化的。但就我而言,它只是一个简单的事件(没有任何值)。
我知道我可以简单地使用闭包并在计时器到期时调用它,如果没有更好的类似组合的解决方案,我会这样做。
这是一个非常简单问题的概念性问题,所以我认为它是自我解释的,而无需我提出代码示例?
解决方法
SwiftUI 与Combine 一起工作的方式是通过.onReceive
,它需要一个发布者。对象可以将发布者(无论是 Timer
还是其他内容)作为属性公开。
组合发布者通过发出值来工作,如果您只需要发出事件发生的信号,您可以发出 ()
又名 Void
值。
顺便说一下,这个对象不必是 ObservableObject
,但也可以是。
class Foo: ObservableObject {
let timer = Timer.publish(every: 1,on: .main,in: .default)
.autoconnect()
.map { _ in } // map to Void
.eraseToAnyPublisher() // optional,but a good practice
}
现在,您可以使用 .onReceive
订阅 timer
事件:
struct ContentView: View {
@StateObject var foo = Foo()
@State var int: Int = 0
var body: some View {
Text("\(int)")
.onReceive(timer) {
self.int += 1
}
}
}
当然,您不仅限于 TimerPublisher。例如,如果发生了一些随机事件,您可以使用 PassthroughSubject
发布一个值:
class Foo {
let eventA: AnyPublisher<Void,Never>
private let subject = PassthroughSubject<Void,Never>()
init() {
eventA = subject.eraseToAnyPublisher()
let delay = Double.random(in: 10...100)
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
// something random happened,notify
self?.subject.send()
}
}
}
,
只是一个想法,但您可以将特定线程专用于该对象吗?然后专门监听和触发该队列上的内容。我以前从未这样做过,但这似乎是一种正确的想法。
https://developer.apple.com/documentation/dispatch/dispatchqueue
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。