首页 > 解决方案 > 内存缓存视图

问题描述

我对 SwiftUI 相当陌生,并试图构建一个包含多个WKWebViews 的应用程序,我可以通过按一下按钮循环。我一直未能在WebViewRepresentables (WKWebKit包装器)之间切换。由于包装 UIKit 和处理所有的委托是一件复杂的事情,我认为有更多的错误空间,并决定创建另一个只有颜色循环的项目。

我正在尝试通过ColorView下面的代码片段中的 s 。

我期待看到这是在 3 秒后。在我到达他们3 秒onAppear{}发送消息 ( )。但是,一旦它针对第一个视图运行,它也会针对所有其他视图运行。当我按下按钮时,另外两个也可以在那里看到文本。

为什么onAppear代码块只运行一次(断点只命中一次)并且结果适用于每个视图,即使它们都是ColorView?

我希望每个视图只生成一次随机数,但在下面的代码片段中,我观察到每次切换到下一个视图时都会生成一个新的随机数。我认为将它们存储在内存数组中可以防止这种情况,因为它们会被实例化一次?

内存缓存视图的正确方法是什么,以便它们可以在它们之间切换(每个只初始化一次并且每次显示时都不会刷新)?

struct ColorView: View {
    @State private var text = ""
    let color: Color
    
    var body: some View {
        VStack {
            Text(text)
            Text("\(Int.random(in: 1..<10))")
            color
        }
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                self.text = "This is after 3 seconds."
            }
        }
    }
}

struct ContentView: View {
    @State private var colors: [ColorView] = [ColorView(color: .red), ColorView(color: .yellow), ColorView(color: .gray)]
    @State private var index = 0
    
    var body: some View {
        VStack {
            Text("page \(index)")
            Button(action: { index += 1; index = index % 3 }, label: { Text("Go through") })
            colors[index]
        }
    }
}

标签: swiftui

解决方案


考虑到 Asperi 评论,但如果你想强制执行这项工作,请按照以下说明了解 SwiftUI 的工作原理:这是因为视图是第一次加载的,并且只有在内部发生变化时才会改变。

如果添加 .id() ,则视图会在 id 发生变化时刷新。

struct ContentView: View { @State private var colors: [ColorView] = [ColorView(color: .red), ColorView(color: .yellow), ColorView(color: .gray)] @State private var index = 0

var body: some View {
    VStack {
        Text("page \(index)")
        Button(action: { index += 1; index = index % 3 }, label: { Text("Go through") })
        Divider()
        colors[index]
            .id(index) //--> add this
    }
}

推荐阅读