【问题标题】:What is the best way to set the ViewModel of a view in SwiftUI在 SwiftUI 中设置视图的 ViewModel 的最佳方法是什么
【发布时间】:2021-06-20 17:14:54
【问题描述】:

我是 MVVM 世界的新手,想知道在呈现新视图时设置新视图的 ViewModel 属性的最佳方法是什么?

我试图在呈现视图的 .fullScreenCover 中初始化 ViewModel 类,但这给我带来了各种各样的问题。这就是我所做的:

struct FirstView: View {
    @State var isActive = false
    var body: some View {
        Text("Tap here to go to SecondView")
            .onTapGesture {
                isActive = true
            }
            .fullScreenCover(isPresented: $isActive, content: {
                SecondView(viewModel: ViewModel(), isActive: $isActive)
            })
    }
    
}
struct SecondView: View {
    @ObservedObject var viewModel: ViewModel
    
    @Binding var isActive: Bool
    
    init(viewModel: ViewModel, isActive: Binding<Bool>) {
        self.viewModel = viewModel
        self._isActive = isActive
    }
    
    var body: some View {
        Button(action: {
            $isActive = false
        }, label: {
            Text("Go back to FirstView")
        })
    }
}

问题是 viewModel 的 init 方法被多次调用。我不确定这是否是因为底层的 FirstView 正在被重绘,尽管它不再出现在屏幕上,或者它是否与在 SecondView 中访问的绑定 isActive var 有关。无论如何,正在创建如此多的视图模型。我不确定这是为什么。但更重要的是我想知道初始化新视图的 viewModel 的正确方法是什么。

我目前正在做的是在 FirstView 的 viewModel 中创建 SecondView 的 viewModel 并传递引用,但感觉很不对。

【问题讨论】:

  • 不确定该链接是关于什么的。我不是在问命名约定。我使用上面的命名来说明问题。这些不是我代码中的名称。问题是关于如何传递视图模型。不是叫什么。谢谢。
  • 你以为你在谈论一个“ViewModel”,但实际上里面有一个空间:它是一个“view model”,一个视图的模型。既然我们有像点这样的现代工具,那么“ViewModel”这个术语仍然存在是令人困惑的。请改变您对此的看法,帮助行业发展。
  • 驼峰式表示空格。我相信这是惯例。我没有称它为视图模型

标签: ios swift xcode swiftui


【解决方案1】:

一般来说,在初始化ViewModel 时应该使用@StateObject。如果只需要在SecondView中,则不需要从FirstView传递给SecondView,可以在SecondView中初始化:

struct SecondView: View {
    @StateObject var viewModel: ViewModel = ViewModel()

但是,如果您需要在第一个视图中引用它,或者希望它在不考虑创建 SecondView 的情况下持续存在,那么您可以使用以下方法在父视图(本例中为 FirstView)中对其进行初始化:

 @StateObject var viewModel = ViewModel()

然后将该对象传递给子视图 (SecondView):

SecondView(viewModel: viewModel...

正如您已经拥有的那样,它应该是子视图中的@ObservedObject

 @ObservedObject var viewModel: ViewModel

或者,您可以将其初始化为 @EnvironmentObject 并将其传递到环境中,而不是通过初始化程序直接从视图到视图传递。


我发现很多人对此有疑问,所以如果你想更好地理解,我制作了一些 YouTube 教程:

How to use @StateObject and @ObservableObject

How to use @EnvironmentObject

SwiftUI Todo App with MVVM

【讨论】:

  • 这正是我想要的。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 2015-11-23
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多