在SwiftUI中,我有几个不同的屏幕。对于每个屏幕,我都有一个ViewController,SwiftUI View和一个组合的EnvironmentObject。组合的EnvironmentObject具有两个可观察的类,一个是ViewModel,另一个是Interactor。
我如何在不使用ViewController的情况下为每个SwiftUI视图使用Interactor和ViewModel?每个视图都有一个不同的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)
})
}
}
}
答案 0 :(得分:0)
环境对象是按类型注入的,因此您可以分别注入视图模型和插入器,如下所示
struct View1<VC1: UIViewController>: View {
@EnvironmentObject var viewModel: ViewModel1
@EnvironmentObject var iterator: Interactor1<VC1>
...
,例如,所有子视图都可以使用它们(基于声明,两个子视图都可以独立使用)
struct SubView1<VC1: UIViewController>: View { // only with view model
@EnvironmentObject var viewModel: ViewModel1
struct SubView2<VC1: UIViewController>: View { // only with iterator
@EnvironmentObject var iterator: Interactor1<VC1>
最后,也是必需的,对于根视图,两个都必须注入到构造中,例如(抓痒的)
View1(...)
.environmentObject(ViewModel1(...))
.environmentObject(Interactor1(...))
顺序无关紧要,按类型插入。
通过Xcode 11.2 / iOS 13.2测试