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:
But if I display it in a second view after a NavigationLink, the drawn line is "pixelated":
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