SwiftUI:从嵌套视图调用方法

Posted

技术标签:

【中文标题】SwiftUI:从嵌套视图调用方法【英文标题】:SwiftUI: calling a method from nested view 【发布时间】:2020-12-04 18:12:09 【问题描述】:

我对 SwiftUI 非常熟悉,为了使我的代码更具可读性,我通常将我的视图分解为更小的视图。

假设我有一个 viewModel,从嵌套视图调用我的 viewModel 方法的最佳方法是什么?现在我将我的 ViewModel 作为每个嵌套视图的参数传递,但我发现它不是非常优化和干净......

有没有办法通知 MyMainView HeaderSubview 的按钮被点击了?例如,我可以使用 Combine 吗?

视图模型

class MyViewModel 
    func fetchSomeData() 
        print("Fetching Some Data")
    

主视图

struct MyMainView: View 

    var myViewModel = MyViewModel()
    var body: some View 
        HeaderView(viewModel: myViewModel)
    


struct HeaderView: View 
    var viewModel: MyViewModel

    var body: some View 
        HeaderSubview(viewModel: viewModel)
    


struct HeaderSubview: View 
    var viewModel: MyViewModel
    var body: some View 
        Button("Search") 
            // I want to call my View Model method here
            viewModel.fetchSomeData()
        
    

【问题讨论】:

【参考方案1】:

你可以将你的类 ObservableObject 注入到环境对象中,这样任何子视图都可以使用它,主视图也可以观察到它。

类似

class MyViewModel: ObservableObject 
    @Published var loading = false
    func fetchSomeData() 
        loading = true
        
        DispatchQueue.global(qos: .background).async 
            print("Fetching Some Data")
            // ... long activity here
            DispatchQueue.main.async  [weak self] in
                self?.loading = false
            
        
        
    


struct MyMainView: View 
    
    @StateObject var myViewModel = MyViewModel()
    var body: some View 
        HeaderView().environmentObject(myViewModel)
        if myViewModel.loading 
            Text("Loading...")
        
    


struct HeaderView: View 
    
    var body: some View 
        HeaderSubview()
    


struct HeaderSubview: View 
    @EnvironmentObject var viewModel: MyViewModel
    var body: some View 
        Button("Search") 
            // I want to call my View Model method here
            viewModel.fetchSomeData()
        
    

【讨论】:

非常感谢,非常明确的答案,你摇滚 :)

以上是关于SwiftUI:从嵌套视图调用方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从swiftui视图调用uikit viewcontroller方法

视图模型中的 Firestore 方法未在 SwiftUI onAppear 方法中调用

SwiftUI - 如何通过视图模型完成调用函数

当 ObservedObject 更改时,在 SwiftUI 视图中未调用 onReceive

iOS14.2 SwiftUI PageTabView 会多次调用 ChildView onAppear 方法

有啥方法可以避免 SwiftUI GeometryReader 阻止嵌套视图在列表中增长?