在 LazyVStack 中使用带有 AsyncImage 的 VStack 会导致图像在滚动时重新加载
Using VStack with AsyncImage inside LazyVStack causes images to reload on scrolling
我正在尝试使用 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)
}
}
}
}
}
}
}
我完全同意你的看法,这是一个奇怪的错误。我猜它发生的原因与 LazyVGrid
选择布局视图的方式有关,并且在这里使用 VStack
给人的印象是要显示多个视图。这对 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")
}
}
}
}
}
}
}
我正在尝试使用 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)
}
}
}
}
}
}
}
我完全同意你的看法,这是一个奇怪的错误。我猜它发生的原因与 LazyVGrid
选择布局视图的方式有关,并且在这里使用 VStack
给人的印象是要显示多个视图。这对 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")
}
}
}
}
}
}
}