如何在SwiftUI中将数据延迟加载到表单/列表中?

时间:2020-10-31 23:41:29

标签: swiftui

我正在ForEach循环中生成Text,并使用Form给出样式,但是在大量数据中它如何工作,我试图使用LazyVStack进行播种,但是我没有成功!我们如何将数据加载到具有大量数据的表单中?

PS:即使在LazyVStack的帮助下,即使是较重的数据,相同的代码也可以在ForEach上正常工作,而无需使用Form或List。我只想让代码与Form或List一起使用。

    struct ContentView: View
{
    
    var body: some View
    {
    Form
    {
        ForEach(0 ..< 1000000) { index in
            Text("Row \(index)")
        }

    }

    
    }

}

2 个答案:

答案 0 :(得分:1)

问题在于,即使以后仅在需要时才显示相应的UI行,静态数据源(以及所有内部依赖项)都会被立即分配。

这里是解决此情况的一种可行方法-使数据容器动态化并按块加载数据(考虑到List / Form重用行)

通过Xcode 12 / iOS 14测试

struct ContentView: View {
    let max = 1000000 // even Int.max, if you want
    let block = 10

    @State private var indices = [0]   // << initially loaded small part

    var body: some View {
        List {
            ForEach(indices, id: \.self) { index in
                Text("Row \(index)")
                    .onAppear {

                        // load next block when last row shown (or can be 
                        // tuned to preload in avance)

                        if indices.last == index && index < max {
                            let next = max - index
                            indices.append(contentsOf:
                                Array(index + 1..<index+(next > block ? block : next)))
                        }
                    }
            }
        }
    }
}

答案 1 :(得分:0)

您要查找的代码是这样:

struct ContentView: View {
    var body: some View
    {
        Form
        {
            ForEach(0 ..< 100000, id: \.self) { index in
                Text("Row \(index)")
            }
        }
    }
}

您应该注意两件事:

首先,您应该为您的ForEach提供一个ID以使用,因为它不一定知道另一个项目。这对于重新排序等非常重要。

第二,我把您的ForEach降低了一个数量级。您要的是一百万行的表格。这仅比渲染引擎合理。没有人会滚动一百万行。它可以工作十万。同样,没有人会滚动浏览十万个项目。

您没有提供的另一件事是数据支持。您的数据来自哪里?您应该限制一次显示的数据量,但这取决于源。例如,如果您使用的是Core Data,则可以限制来自商店的对象。您所显示的数据不应超过用户可能使用的数据。如果是这样,您就不会考虑要完成的任务。