SwiftUI: How to draw filled and stroked shape?
You can also use strokeBorder
and background
in combination.
Code:
Circle()
.strokeBorder(Color.blue,lineWidth: 4)
.background(Circle().foregroundColor(Color.red))
Result:
You can draw a circle with a stroke border
struct ContentView: View {
var body: some View {
Circle()
.strokeBorder(Color.green,lineWidth: 3)
.background(Circle().foregroundColor(Color.red))
}
}
My workaround:
import SwiftUI
extension Shape {
/// fills and strokes a shape
public func fill<S:ShapeStyle>(
_ fillContent: S,
stroke : StrokeStyle
) -> some View {
ZStack {
self.fill(fillContent)
self.stroke(style:stroke)
}
}
}
Example:
struct ContentView: View {
// fill gradient
let gradient = RadialGradient(
gradient : Gradient(colors: [.yellow, .red]),
center : UnitPoint(x: 0.25, y: 0.25),
startRadius: 0.2,
endRadius : 200
)
// stroke line width, dash
let w: CGFloat = 6
let d: [CGFloat] = [20,10]
// view body
var body: some View {
HStack {
Circle()
// ⭐️ Shape.fill(_:stroke:)
.fill(Color.red, stroke: StrokeStyle(lineWidth:w, dash:d))
Circle()
.fill(gradient, stroke: StrokeStyle(lineWidth:w, dash:d))
}.padding().frame(height: 300)
}
}
Result:
Seems like it's either ZStack
or .overlay
at the moment.
The view hierarchy is almost identical - according to Xcode.
struct ContentView: View {
var body: some View {
VStack {
Circle().fill(Color.red)
.overlay(Circle().stroke(Color.blue))
ZStack {
Circle().fill(Color.red)
Circle().stroke(Color.blue)
}
}
}
}
Output:
View hierarchy:
For future reference, @Imran's solution works, but you also need to account for stroke width in your total frame by padding:
struct Foo: View {
private let lineWidth: CGFloat = 12
var body: some View {
Circle()
.stroke(Color.purple, lineWidth: self.lineWidth)
.overlay(
Circle()
.fill(Color.yellow)
)
.padding(self.lineWidth)
}
}