ios - 在 SwiftUI 中加载异步请求时显示事件指示器

标签 ios swift cocoa swiftui

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

我尝试从这个问题中实现一个事件指示器,我只是不知道如何以及何时停止它:Activity indicator in SwiftUI

My 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
    }
}

我的 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)
        }
    }
}

最后,我的 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()
    }
}

结果:

how to stop loading

最佳答案

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

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

并且事件指示器应该绑定(bind)到它,例如

ActivityIndicatorView(isShowing: $model.loading) {

关于ios - 在 SwiftUI 中加载异步请求时显示事件指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58957327/

相关文章:

ios - UIImageView 的 UITextField subview 不响应触摸事件

swift - 你能在 Swift 中评估一个字符串吗?

iphone - 算法:Cocoa Touch 中的数组数组(可能使用 NSCountedSet)

macos - 无标题 NSDocument 的建议保存名称

ios - 如何从 iOS 类 "CAEAGLLayer"获取 _CAEAGLNativeWindow

ios - collectionview 在 tableview 单元格内重复

iphone - 使用标签以编程方式创建后在 iOS 中移动多个图像

ios - 缩进 UITextField 文本和占位符

ios - Swift 从数据(字节数组)创建 URL 对象而不写入磁盘

cocoa - 如何在Cocoa中使用system调用curl