SwiftUI ScrollView不显示从ObservableObject获取的结果

时间:2019-11-23 12:08:27

标签: ios swift scrollview swiftui

我试图通过单击“获取”按钮从api获取数据,并通过ScrollView中的ForEach循环显示它们。

我正在使用MVVM模型。提取本身发生在ObservableObject类中。

不幸的是,ScrollView不显示内容。如果我使用列表而不是ScrollView,则可以正常工作。

你知道我在这里想念什么吗?

非常感谢您的帮助!

import SwiftUI

struct Photo: Identifiable, Decodable {

    let id = UUID()
    let title: String
}

class ContentViewModel: ObservableObject {

    let api = "https://jsonplaceholder.typicode.com/photos"

    @Published var photos: [Photo] = []

    func fetchData() {
        print("Fetching started")
        guard let url = URL(string: api) else { return }

        URLSession.shared.dataTask(with: url) { data, _, _ in
            DispatchQueue.main.async {
                self.photos = try! JSONDecoder().decode([Photo].self, from: data!)
                print("Fetching successfull. Fetched \(self.photos.count) photos.")
            }
        }.resume()
    }
}

struct ContentView: View {

    @ObservedObject var contentVM = ContentViewModel()

    var body: some View {
        NavigationView {
            ScrollView {
                ForEach(self.contentVM.photos) { photo in
                    Text(photo.title)
                }
            }
            .navigationBarTitle("Home")
            .navigationBarItems(trailing: Button(action: {

                self.contentVM.fetchData()

                }, label: {
                    Text("Fetch")
            }))
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

1 个答案:

答案 0 :(得分:1)

您什么都没错过,我认为问题在于渲染内容。即使在您的示例中,数据仍显示在真实设备(iPhone 7 iOS 13.1.1)上,但延迟很长。尝试使用较少的内容或帮助ScrollView进行对齐。我尝试了这一点-在设备上运行速度更快,但仅在设备上运行:

class ContentViewModel: ObservableObject {

    let api = "https://jsonplaceholder.typicode.com/photos"

    @Published var photos: [Photo] = []
    @Published var first100Photos: [Photo] = []

    func fetchData() {
        print("Fetching started")
        guard let url = URL(string: api) else { return }

        URLSession.shared.dataTask(with: url) { data, _, _ in
            DispatchQueue.main.async {
                self.photos = try! JSONDecoder().decode([Photo].self, from: data!)
                for index in 0...100 {
                    self.first100Photos.append(self.photos[index])
                }
                print("Fetching successfull. Fetched \(self.photos.count) photos.")
            }
        }.resume()
    }
}

struct ContentView: View {

    @ObservedObject var contentVM = ContentViewModel()

    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                VStack {
                    ForEach(self.contentVM.first100Photos) { photo in
                        Text(photo.title)
                    }
                }

            }
            .navigationBarTitle("Home")
            .navigationBarItems(trailing: Button(action: {

                self.contentVM.fetchData()

                }, label: {
                    Text("Fetch")
            }))
        }
    }
}