想要显示一个图片列表,但是图片列表支持刷新功能,在这个时候遇到了一个更新的时候图片没有刷新的问题。
出问题的原因是由于foreach的使用上导致的,感觉foreach的刷新还是跟其定义的id有很大的关系,因此后续在用的时候尽量避免在foreach中使用数组下标之类的写法。
出问题的代码如下:
struct CView: View {
var content: String
@State var nsimage: NSImage = NSImage()
init(content: String) {
self.content = content
}
var body: some View {
Image(nsImage: nsimage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 50, height: 50)
.task {
nsimage = .init(named: content) ?? .init()
}
}
}
struct ContentView: View {
@State var contents: [String] = ["A", "B"]
var body: some View {
ForEach(0..<contents.count, id: \.self) { index in
CView(content: contents[index])
}
.task {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
contents = ["C", "D", "E"]
}
}
}
}
这个时候由于数组的下标只增加了一个,所以前两个元素没有被更新到。不过这个也是在使用Image重新赋值的时候才有这个问题,如果说用到的是Text此类的元素就没有这种问题,也是挺奇怪的。
解决这个问题也简单,只需要把foreach的ID给替换成唯一的即可。
ForEach(Array(contents.enumerated()), id: \.element) { index, element in
// xxx
}
不过这种还是比较难排查的,所以说以后还是尽量避免直接使用下标当做foreach的ID,可以避免出现很多更新问题。