5

我正在尝试使用 SwiftUI 中的新 AsyncImage 显示一长串带有标题的图像。我注意到,当我将 VStack 放在 AsyncImage 周围并滚动图像时,每次向上或向下滚动时它都会重新加载图像。当没有 VStack 时,我看不到重新加载并且图像似乎保持缓存。

有没有办法让 VStack 在滚动时不重新加载图像,以便我可以在每个图像下添加文本?

这是一个工作示例。尝试使用和不使用 VStack 滚动。

import SwiftUI

struct TestView: View {

    let url = URL(string: "https://picsum.photos/200/300")

    let columns: [GridItem] = [.init(.fixed(110)),.init(.fixed(110)),.init(.fixed(110))]

    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns) {
                ForEach(0..<20) { _ in
                    // VStack here causes to images to reload on scrolling
                    VStack {
                        AsyncImage(url: url) { image in
                            image
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                        } placeholder: {
                            Image(systemName: "photo")
                                .imageScale(.large)
                                .frame(width: 110, height: 110)
                        }
                    }
                }
            }
        }
    }
}
4

1 回答 1

7

我完全同意你的看法,这是一个奇怪的错误。我猜想它发生的原因与LazyVGrid选择布局视图的方式有关,并且在VStack这里使用 a 给人的印象是有多个视图要显示。这对 Apple 来说是一项糟糕的工作,但这就是我解决它的方法:只需将VStacks内部文件放入AsyncImage. 我不完全确定最初的错误是什么,但我知道这可以解决它。

struct MyTestView: View {
    let url = URL(string: "https://picsum.photos/200/300")
    let columns: [GridItem] = [.init(.fixed(110)),.init(.fixed(110)),.init(.fixed(110))]

    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns) {
                ForEach(0..<20) { i in
                    AsyncImage(url: url) { image in
                        VStack {
                            image
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                            
                            Text("label \(i)")
                        }
                    } placeholder: {
                        VStack {
                            Image(systemName: "photo")
                                .imageScale(.large)
                                .frame(width: 110, height: 110)
                            
                            Text("image broken")
                        }
                    }
                }
            }
        }
    }
}
于 2021-10-02T17:48:46.297 回答