为按钮动作事件实施反应式编程的最佳方法是什么?
关于指南和示例,我只找到了带有 SwiftUI @State
的示例。
我的意思是这样的:
@State var isVisible = false
....
Button(action: {
self.isVisible.toggle()
}
....
if isVisible {
Text("texty text")
}
但是,如果我想执行后台任务怎么办?
显而易见的方法是在viewModel?.pleaseDoAction()
内调用Button.action(
,并创建在pleaseDoAction()
内部触发的自定义主题:
final class ViewModel {
func pleaseDoAction() {
mySubject.send("some")
}
}
但这是 SwiftUI +合并的正确架构方法吗? 简而言之,按钮操作应该是发布者,但不是。
答案 0 :(得分:1)
两种方法:
@Published
import SwiftUI
final class ViewModel: ObservableObject {
@Published var isVisible = false
}
struct SampleView: View {
@ObservedObject var model = ViewModel()
Button(action: {
self.model.isVisible.toggle()
}) {
Text("...")
}
}
Combine
的发布者import Combine
import SwiftUI
final class ViewModel: ObservableObject {
let objChanges = ObservableOjbectPublisher()
var isVisible: Bool = false {
willSet {
objChanges.send()
}
}
}
第二个视图与第一个视图非常相似。
另外,Paul Hudson和WWDC2019的课程可能会提供有关上述包装及其用法的更多见解
答案 1 :(得分:1)
@Partha G的ViewModel方法可能是最合适的,但这是一种不需要视图模型的简单方法。
作为警告,如果您的视图这样做,则此方法可能无法很好地与SwiftUI视图刷新配合。但是对于这种非常简单的情况,它似乎运行良好。
// Your view with a button:
import SwiftUI
import Combine
struct MyAwesomeView: View {
public var buttonPressedSubject = PassthroughSubject<Void, Never>()
var body: some View {
Button("Push This Button", action: {
self.buttonPressedSubject.send()
})
}
}
import Combine
class A {
private var cancelBag = Set<AnyCancellable>()
private let myView: MyAwesomeView
init(view: MyAwesomeView) {
self.myView = view
myView.buttonPressedSubject
.sink { (_) in
print("The button was pressed.")
}
.store(in: &cancelBag)
}
}
// <#Copy-paste code from above here#>
import PlaygroundSupport
let playgroundView = MyAwesomeView()
let playgroundExample = A(view: playgroundView)
PlaygroundPage.current.setLiveView(playgroundView)