0

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.

enter image description here

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.

  • Really looks like a bug (due to gradient redrawing on navigation). Btw, you don't need `NavigationView` in second view (but it's not about this issue). – Asperi Apr 13 '22 at 11:46
  • @Asperi thanks I've updated the second view code. As you said, the issue is not related to second NavigationView. – Davide Pagin Apr 13 '22 at 12:29
  • After looking at it, I pulled the linear gradient out of the view, and saw essentially the same thing. I am not sure it is a glitch so much as the rendering of the transition. Your "dirty fix" is probably not so dirty, other than having to use Introspect as we never know when the UIKit underpinnings will be replaced, but I would look at it as more of a styling issue than a glitch. – Yrb Apr 13 '22 at 15:00

0 Answers0