在 SwiftUI 中加载异步请求时显示活动指示器

Old*_*mes 7 cocoa ios swift swiftui

我有一个显示从 API 获取数据的列表的基本视图。我想在从 API 检索数据时实现一个活动指示器。在 MVC 中,我们可以使用委托和协议,让视图控制器继承协议,在模型完成获取数据后,我们调用委托告诉视图控制器数据已完成检索(现在隐藏活动指示器等.) 如何在 SwiftUI 中实现类似的东西,它是 MVVM 风格?

我已经尝试从这个问题实现一个活动指示器,我只是不知道如何以及何时停止它:SwiftUI 中的活动指示器

我的 SourcesViewModel(它从 newsapi.org 获取新闻文章来源)

import UIKit

class SourcesViewModel: Identifiable {

    let id = UUID()

    let source: Sources

    init(source: Sources) {
        self.source = source
    }

    var name: String {
        return self.source.sourceName
    }

    var description: String {
        return self.source.sourceDescription
    }
}
Run Code Online (Sandbox Code Playgroud)

我的 SourcesListViewModel:

import Combine

class SourcesListViewModel: ObservableObject {

    init() {
        fetchSources()
    }

    @Published var sources = [SourcesViewModel]()
    private func fetchSources() {
        NetworkManager.shared.getSourceData { (sources) in
            self.sources = sources.map(SourcesViewModel.init)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我的 SourcesView:

import SwiftUI

struct SourcesView: View {
    @ObservedObject var model = SourcesListViewModel()

    var body: some View {
        ActivityIndicatorView(isShowing: .constant(true)) {
            NavigationView {
                List(self.model.sources) { source in
                    VStack(alignment: .center) {
                        Text(source.name)

                        Text(source.description)
                            .foregroundColor(.secondary)
                            .lineLimit(3)
                    }
                    .navigationBarTitle(Text("Sources"), displayMode: .inline)
                }
            }
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        SourcesView()
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

如何停止加载

Asp*_*eri 5

您的视图模型应该具有加载状态,如下所示

@Published var loading = false
private func fetchSources() {
    self.loading = true
    NetworkManager.shared.getSourceData { (sources) in
        self.sources = sources.map(SourcesViewModel.init)
        self.loading = false
    }
}
Run Code Online (Sandbox Code Playgroud)

和活动指示器应该绑定到它,比如

ActivityIndicatorView(isShowing: $model.loading) {
Run Code Online (Sandbox Code Playgroud)

  • 如果是绑定的话,我没看到ActivityIndi​​catorView是什么,那还不如直接`$model.loading`。 (2认同)