Home > OS >  SwiftUI Path is pixelated when in second Navigation View
SwiftUI Path is pixelated when in second Navigation View

Time:11-22

I have a strange behavior on my SwiftUI app. I draw a Path with a linear gradient as stroke color.

This path is displayed like this in my view:

GeometryReader { proxy in
    LinePath(width: proxy.size.width, height: proxy.size.height)
        .stroke(gradient, lineWidth: 3)
}
.frame(height:200)
.padding()

(LinePath struct extends Shape and draw the Path)
When this code is displayed on first view, it draws correctly:

correct

But if I display it in a second view after a NavigationLink, the drawn line is "pixelated":

issue

As it may be difficult to understand and there is quite lot of code (for a web page), I did a demo project you can get here.

To test it, you can open testprojectApp.swift and comment/uncomment parts:

ContentView() // <--- Uncomment this to get the issue
//SubView() // <--- Uncomment this and it works

If you call SubView (where this LinePath is drawn), it works. If you call ContentView that will display a button to navigate to SubView, it draws a pixelated line.

Notes:

  • If I don't set a height, it is never pixelated (.frame(height:200)).
  • If I don't use a gradient but a simple color (as .blue), it is never pixelated.

EDIT: I've found a "workaround", to redraw the line 0.01s after it appeared and change its height. It visually "works" but of course it is not a good method...

@State var height: CGFloat = 0
var body: some View {
    
    GeometryReader { proxy in
        LinePath(width: proxy.size.width, height: proxy.size.height)
            .stroke(gradient, lineWidth: 3)
    }
    .frame(height:height)
    .padding()
    .onAppear() {
        DispatchQueue.main.asyncAfter(deadline: .now()   0.01) {
            height = 200
        }
    }
}

CodePudding user response:

You can add .drawingGroup() and it seems to resolve the issue without having to use the delay:

GeometryReader { proxy in
    LinePath(width: proxy.size.width, height: proxy.size.height)
        .stroke(gradient, lineWidth: 3)
}
.frame(height:200)
.padding()
.drawingGroup() //<-- here
  • Related