我想为使用SwiftUI和Combine实现的架构实现导航器/路由器。简而言之,View
将与viewModel
共享Router
。当View
触发viewModel
上的更改时,Router
应该导航到新工作表。
这是我的代码的一个版本,我在其中直接将viewModel
从View
传递到Router
。有什么问题吗?我最大的疑问是,由于我在@ObservedObject
和Router
上都使用View
,因此创建了viewModel
的两个不同实例。
class BootViewModel:ObservableObject{
@Published var presentSignIn = false
}
struct BootView: View {
@ObservedObject var viewModel:BootViewModel
var navigator:BootNavigator<BootView>? = nil
init(viewModel:BootViewModel) {
self.viewModel = viewModel
self.navigator = BootNavigator(view: self, viewModel: viewModel)
self.navigator.setSubscriptions()
}
var body: some View {
VStack{
Text("Hello")
Button("Button"){
self.viewModel.presentSignIn.toggle()
}
}
}
}
class BootNavigator<T:View>{
var view:T? = nil
@ObservedObject var viewModel:BootViewModel
init(view:T, viewModel:BootViewModel) {
self.view = view
self.viewModel = viewModel
}
func setSubscriptions(){
subscribe(onSigninPressed: $viewModel.presentSignIn)
}
func subscribe(onSigninPressed : Binding<Bool>){
_ = view.sheet(isPresented: $viewModel.presentSignIn){
SignInView()
}
}
}
SignInView
? 答案 0 :(得分:2)
此
view.sheet(isPresented: $viewModel.presentSignIn){
SignInView()
必须(直接或通过计算属性或函数)位于body
中的某个位置,但位于主体的ViewBuilder中
答案 1 :(得分:2)
一些注意事项,我必须在这里指出:
set /p choice=
和SwiftUI UIView
之间是有区别的。所有SwiftUI View
都是值类型!因此,当您传递它们时,它们将被复制。注意这一点。
如果您想要整个应用程序使用一个像常规 navigator 这样的实例,则可以使用单例模式。但是SwiftUI Universe中有一种更好的方法称为View
对象。您可以利用它。
要刷新视图(包括显示内容),必须在@Environment
的内部中进行编码。但是它可以直接通过函数等间接编写。