【发布时间】:2020-02-28 11:07:44
【问题描述】:
在 SwiftUI 中,我有几个不同的屏幕。对于每个屏幕,我都有一个 ViewController、SwiftUI View 和一个组合的 EnvironmentObject。组合后的 EnvironmentObject 有两个 observable 类,一个是 ViewModel,另一个是 Interactor。
如何在不使用 ViewController 的情况下为每个 SwiftUI 视图使用 Interactor 和 ViewModel?并且每个 View 都有不同的 EnvironmentObject。
import SwiftUI
import Combine
class ViewModel1: ObservableObject {
//Published data for view
@Published var text: String
init(text: String) {
self.text = text
}
}
class Interactor1<VC: UIViewController>: ObservableObject {
let vc: VC
let viewModel: ViewModel1?
init(vc: VC, viewModel: ViewModel1?) {
self.vc = vc
self.viewModel = viewModel
}
func buttonClicked() {
//present second ViewController by using vc.present...
}
}
class CombinedObject<VC: UIViewController>: ObservableObject {
@Published var interactor: Interactor1<VC>
@Published var viewModel: ViewModel1
var anyCancellable: AnyCancellable? = nil
var anyCancellable2: AnyCancellable? = nil
init(vc: VC, index: Int) {
viewModel = ViewModel1(text: "text1")
interactor = Interactor1(vc: vc, viewModel: nil)
interactor = Interactor1(vc: vc, viewModel: viewModel)
anyCancellable = interactor.objectWillChange.sink { (_) in
self.objectWillChange.send()
}
anyCancellable2 = viewModel.objectWillChange.sink { (_) in
self.objectWillChange.send()
}
}
}
class ViewController1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let combinedObject = CombinedObject(vc: self, index: 0)
let view1 = View1<ViewController1>().environmentObject(combinedObject)
let hostingController = UIHostingController(rootView: view1)
self.addChild(hostingController)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
}
}
struct View1<VC1: UIViewController>: View {
@EnvironmentObject var combinedObject: CombinedObject<VC1>
var body: some View {
VStack() {
Button(action: {
self.combinedObject.interactor.buttonClicked()
}, label: {
Text(self.combinedObject.viewModel.text)
})
}
}
}
【问题讨论】: