I have an array of Color, which I am using this array for rendering a View in multiple time, Each element of this array has a State role for a View that works with Binding, So we have an array as array of State, which every single element of that array is going used for feeding a View which needs Binding, the codes working, but every single small update to this array make ForEach render the all array, which is unnecessary, I want to correct or modify my code to stop this unnecessary renders! For example when I change 1 element to Color.black, it is understandable that SwiftUI render a new View for this element but in the fact my codes make SwiftUI render all array! or when I add new element to end of array, the same thing happens! How can I solve this problem? thanks.
PS: if you think that index or id:.self make this issue, I have to say No, because I must and I have to use index, because Binding needs an State object, and it is only possible with index, I cannot use item version of ForEach, because Binding cannot update it.
var randomColor: Color { return Color(red: Double.random(in: 0...1), green: Double.random(in: 0...1), blue: Double.random(in: 0...1)) }
struct BindingWay: View {
@State private var arrayOfColor: [Color] = [Color]()
var body: some View {
VStack(spacing: 0) {
ForEach(arrayOfColor.indices, id:\.self) { index in
CircleViewBindingWay(colorOfCircle: $arrayOfColor[index])
}
Spacer()
Button("append new Color") {
arrayOfColor.append(randomColor)
}
.padding(.bottom)
Button("update last element color to black") {
if arrayOfColor.count > 0 {
arrayOfColor[arrayOfColor.count - 1] = Color.black
}
}
.padding(.bottom)
}
.shadow(radius: 10)
}
}
struct CircleViewBindingWay: View {
@Binding var colorOfCircle: Color
init(colorOfCircle: Binding<Color>) { print("initializing CircleView"); _colorOfCircle = colorOfCircle }
var body: some View {
print("rendering CircleView")
return Circle()
.fill(colorOfCircle)
.frame(width: 50, height: 50, alignment: .center)
.onTapGesture { colorOfCircle = colorOfCircle.opacity(0.5) }
}
}