Michael Long
2 min readJul 28, 2020

--

I think the problem you were seeing with the rendering is a direct result of not correctly managing the view graph. When you swap view A for view B, SwiftUI will diff the view graph, see a new view, and rebuild the interface accordingly.

This is not a bug.

I strongly suggest that you go to the Apple developer site and rewatch the SwiftUI Essentials video from WWDC ’19, paying particular attention to the segment fro 28:00 to 30:00.

During that segment the presenter discusses changing much of the type of logic your button is using from “if” based to logic contained within the modifier itself.

In other words, if we want to conditionally change the color of a button’s background, we would NOT do…

if self.isEnabled {
button
.background(Color.blue)
} else {
button
.background(Color.gray)
}

“If” should only be used when you actually want to add or remove views from the view hierarchy. Instead, you want to push your condition into your modifier.

button
.background(self.isEnabled ? Color.blue : Color.gray)

If your logic is too complex, say you want different colors for enabled, disabled, pressed, etc., then simply push that logic out to functions on the view.

button
.background(self.getBackgroundColor())
.foregroundColor(self.getForegroundColor())
.opacity(self.getOpacity())
...func getBackgroundColor() ->) Color {
if isPressed {
return Color.purple
} else if isEnabled {
// and so on...
}

Pushing the condition into the modifier helps SwiftUI maintain the view graph and results in better performance.

It also avoids some of the interface glitches that you seemed to be seeing, the problem with group, and allows SwiftUI to correctly animate changes to the interface.

Hope this helps.

--

--

Michael Long
Michael Long

Written by Michael Long

I write about Apple, Swift, and SwiftUI in particular, and technology in general. I'm also a Lead iOS Engineer at InRhythm, a modern digital consulting firm.

No responses yet