SwiftUI ForEach update issue

I want to display a list of pictures, but the list of pictures supports the refresh function. At this time, I encountered a problem that the pictures were not refreshed during the update.
The reason for the problem is due to the use of foreach. I feel that the refresh of foreach has a lot to do with the id defined by it. Therefore, try to avoid using array subscripts in foreach when using it later.
The problematic code is as follows:

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"]
		    }
		}
	}
}

At this time, because the subscript of the array has only increased by one, the first two elements have not been updated. However, this problem only occurs when the image is reassigned. It is quite strange to say that there is no such problem when using elements such as Text.

Solving this problem is also simple, just replace the ID of foreach with a unique one.

ForEach(Array(contents.enumerated()), id: \.element) {
    
     index, element in
	// xxx
}

However, this is still relatively difficult to troubleshoot, so in the future, try to avoid directly using the subscript as the ID of the foreach, which can avoid many update problems.

Guess you like

Origin blog.csdn.net/xo19882011/article/details/129853825