0

我有一个应用程序,它最终会显示一长串数据。除了测试 Lazy Stacks、加载异步和其他技术之外,我还想提供一条加载消息。有趣的是,似乎只有最原子的视图(在这种情况下是 a Scrollview,而不是 a List)被重新计算。代码如下:

struct MainView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @ObservedObject var nodeSet: NodeSet
    
    @State private var viewIsLoaded: Bool = false

    var body: some View {
        
        VStack {
            
            SectionBar(nodeSet: nodeSet, viewIsLoaded: $viewIsLoaded)
                .frame(maxWidth: .infinity, maxHeight: 40)
            
            Divider()
            
            DataView(nodeSet: nodeSet, viewIsLoaded: $viewIsLoaded)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

struct DataView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @ObservedObject var nodeSet: NodeSet

    @Binding var viewIsLoaded: Bool

    var body: some View {
        ZStack {
            ScrollView {
                ForEach(nodeSet.nodes.sorted().indexed(), id: \.1.self) { index, node in
                    NodeView(node: node)
                        .onAppear{ 
                            if index+1 == nodeSet.nodes.count { 
                                viewIsLoaded = true
                                print("Node List has Loaded.") // 1
                            } 
                        }
                }
                .onAppear{ print("ForEach Loaded") } // 2
            }
            VStack {
                Text("Loading...")
                    .padding()
                    .background(Color(.systemGray3))
                    .border(Color("AccentColor"))
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color(.systemGray2).opacity(0.5))
            .isVisible(!viewIsLoaded) // convenience view extension
        }
        .onAppear{ print("ZStack Loaded") } // 3
    }
}

三行中的print所有 3 行都在视图的初始加载时打印,但是当更改列表时(这就是 SectionBar 所做的,我已经删除了过滤代码),只有 #3 会在重新计算数据时打印。很明显,ForEach 和 ZStack 没有被重绘,只有 ForEach 中的单个元素。添加indexed()感觉有点复杂,在// 1打印之后和数据出现之前仍然有大约 1/4 秒的延迟,这让我相信那里有一个隐藏的步骤。

测试视图数据是否已加载的最可靠方法是什么,以及在行//1和出现的视图之间发生了什么?或者,创建加载消息的更好方法是什么?

提前致谢。

4

0 回答 0