It seems there is a visual glitch while I navigate between views implemented with SwiftUI
that are using LinearGradient
as background. In my test case there is a very small vertical flashing line on the left of the screen during navigation animation (the background is a LinearGradient
where top color is a light gray and the bottom color is a dark gray)
If I use simple colors as background, this glitch does not happen
Here is the code I use for testing with Xcode Playground (the same happens with real devices/simulators)
import SwiftUI
import PlaygroundSupport
struct FirstLinearGradientView: View {
var body: some View {
NavigationView {
VStack {
Spacer()
Text("First view")
.foregroundColor(.white)
HStack {
Spacer()
NavigationLink(destination: SecondLinearGradientView()) {
Text("Go to next view")
}
Spacer()
}
Spacer()
}.background(
LinearGradient(
gradient: Gradient(
colors: [
Color(hex: 0x413741),
Color(hex: 0x0D0B0D)
]),
startPoint: .top,
endPoint: .bottom
)
)
}
.frame(width: 400, height: 600)
}
}
struct SecondLinearGradientView: View {
var body: some View {
VStack {
Spacer()
HStack {
Spacer()
Text("Second view")
.foregroundColor(.white)
Spacer()
}
Spacer()
}.background(
LinearGradient(
gradient: Gradient(
colors: [
Color(hex: 0x413741),
Color(hex: 0x0D0B0D)
]),
startPoint: .top,
endPoint: .bottom
)
)
.frame(width: 400, height: 600)
}
}
extension Color {
init(hex: Int, opacity: Double = 1.0) {
let red = Double((hex & 0xFF0000) >> 16) / 255.0
let green = Double((hex & 0xFF00) >> 8) / 255.0
let blue = Double((hex & 0xFF) >> 0) / 255.0
self.init(.sRGB, red: red, green: green, blue: blue, opacity: opacity)
}
}
PlaygroundPage.current.setLiveView(FirstLinearGradientView())
There is a screenshot during the animation transition where you can see the unexpected white line which also does a strange flash.
I don't know if I can fix this or it's an iOS/SwiftUI bug.
UPDATE:
I found a dirty fix. Using Introspect and accessing its UIViewController
, I set the view background color to clear and I do not see the glitch because I simply hide it. Until I find a better solution, I'll keep this fix.