Debugging redraws and understanding view identity
Noticing view redraws
One trick I use in my projects is that I introduce a debug only random border into my views, this means that whenever view gets re-render the color of the border changes, this is noticable and let's me investigate further by employing Self._printChanges() to find the culprit.
extension Color {
static func random() -> Color {
return Color(red: Double.random(in: 0...1), green: Double.random(in: 0...1), blue: Double.random(in: 0...1))
}
}
extension View {
@ViewBuilder
func debugBorder() -> some View {
#if DEBUG
self.border(Color.random)
#else
self
#endif
}
}
Understanding view identity
View identity is core to SwiftUI workings, whenever you see @State variables the way they work underneath is by using global reference store keyed by the view identity, thus when you cause views to loose their identity their data will also get lost.
Ano-opmodifier is a modifier that is doing nothing to the actual display, like adding.clearbackground.
In this lesson I show you how you should always prefer no-op modifiers over conditional branches:
// Different Identities
if flag {
ViewWithState()
.background(Color.red)
.animation(.easeInOut(duration: 2), value: flag)
} else {
ViewWithState()
.animation(.easeInOut(duration: 2), value: flag)
}
// Single identity
// .clear option becomes a no-op
ViewWithState()
.background(flag ? .red : .clear)
.animation(.easeInOut(duration: 2), value: flag)
Download