Here is the RoundedStar code adapted as an animatable SwiftUI Shape:
// Five-point star with rounded tips
struct RoundedStar: Shape {
var cornerRadius: CGFloat
var animatableData: CGFloat {
get { return cornerRadius }
set { cornerRadius = newValue }
}
func path(in rect: CGRect) -> Path {
var path = Path()
let center = CGPoint(x: rect.width / 2, y: rect.height / 2)
let r = rect.width / 2
let rc = cornerRadius
let rn = r * 0.95 - rc
// start angle at -18 degrees so that it points up
var cangle = -18.0
for i in 1 ... 5 {
// compute center point of tip arc
let cc = CGPoint(x: center.x + rn * CGFloat(cos(Angle(degrees: cangle).radians)), y: center.y + rn * CGFloat(sin(Angle(degrees: cangle).radians)))
// compute tangent point along tip arc
let p = CGPoint(x: cc.x + rc * CGFloat(cos(Angle(degrees: cangle - 72).radians)), y: cc.y + rc * CGFloat(sin(Angle(degrees: (cangle - 72)).radians)))
if i == 1 {
path.move(to: p)
} else {
path.addLine(to: p)
}
// add 144 degree arc to draw the corner
path.addArc(center: cc, radius: rc, startAngle: Angle(degrees: cangle - 72), endAngle: Angle(degrees: cangle + 72), clockwise: false)
// Move 144 degrees to the next point in the star
cangle += 144
}
return path
}
}
The code is very similar to the UIBezierPath version except that it uses the new Angle type which provides easy access to both degrees and radians. The code to draw the star rotated was removed because it is easy to add rotation to a SwiftUI shape with the .rotationEffect(angle:) view modifier.
Demonstration:
Here is a demonstration that show the animatable qualities of the cornerRadius setting as well as showing what the various cornerRadius settings look like on a full-screen star.

struct ContentView: View {
@State private var radius: CGFloat = 0.0
var body: some View {
ZStack {
Color.blue.edgesIgnoringSafeArea(.all)
VStack(spacing: 40) {
Spacer()
RoundedStar(cornerRadius: radius)
.aspectRatio(1, contentMode: .fit)
.foregroundColor(.yellow)
.overlay(Text(" cornerRadius: \(Int(self.radius)) ").font(.body))
HStack {
ForEach([0, 10, 20, 40, 80, 200], id: \.self) { value in
Button(String(value)) {
withAnimation(.easeInOut(duration: 0.3)) {
self.radius = CGFloat(value)
}
}
.frame(width: 50, height: 50)
.foregroundColor(.black)
.background(Color.yellow.cornerRadius(8))
}
}
Spacer()
}
}
}
}
Running in Swift Playgrounds on iPad
This runs beautifully on an iPad in the Swift Playgrounds app. Just add:
import PlaygroundSupport
at the top and
PlaygroundPage.current.setLiveView(ContentView())
at the end.
Using the RoundedStar shape to create EU Flag

struct ContentView: View {
static let flagSize: CGFloat = 234 // Change this to resize flag
let flagHeight: CGFloat = flagSize
let flagWidth: CGFloat = flagSize * 1.5
let radius: CGFloat = flagSize / 3
let starWidth: CGFloat = flagSize / 9
let pantoneReflexBlue = UIColor(red: 0, green: 0x33/0xff, blue: 0x99/0xff, alpha: 1)
let pantoneYellow = UIColor(red: 1, green: 0xcc/0xff, blue: 0, alpha: 1)
var body: some View {
ZStack {
Color(pantoneReflexBlue).frame(width: flagWidth, height: flagHeight, alignment: .center)
ForEach(0..<12) { n in
RoundedStar(cornerRadius: 0)
.frame(width: starWidth, height: starWidth)
.offset(x: radius * cos(CGFloat(n) / CGFloat(12) * 2 * .pi), y: radius * sin(CGFloat(n) / CGFloat(12) * 2 * .pi))
.foregroundColor(Color(pantoneYellow))
}
}
}
}