SwiftUI:从嵌套视图调用方法

SwiftUI: calling a method from nested view

我对 SwiftUI 很陌生,为了让我的代码更具可读性,我通常将我的视图分解成更小的视图。

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

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

ViewModel

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()
        }
    }
}

你可以制作你的 class 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()
        }
    }
}

backup