如何创建 SwiftUI RoundedStar 形状?
Posted
技术标签:
【中文标题】如何创建 SwiftUI RoundedStar 形状?【英文标题】:How to Create a SwiftUI RoundedStar Shape? 【发布时间】:2020-08-29 18:04:17 【问题描述】:这是一个自我回答的问题,在 Stack Overflow 上完全可以接受(甚至鼓励)。重点是分享一些对他人有用的东西。
SwiftUI 有一个 RoundedRectangle
Shape
。最好有一个五角星形,尖端圆润,可用于填充、剪切和动画。
此Stack Overflow answer 展示了如何使用UIBezierPath
将RoundedStar
作为自定义UIView
。
如何将这段代码改编为SwiftUI
作为可以动画的Shape
?
【问题讨论】:
【参考方案1】:这是改编为动画 SwiftUI 的 RoundedStar
代码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
代码与UIBezierPath
版本非常相似,只是它使用了新的Angle
类型,可以轻松访问degrees
和radians
。移除了绘制旋转星形的代码,因为使用 .rotationEffect(angle:)
视图修饰符很容易为 SwiftUI 形状添加旋转。
演示:
这是一个演示,展示了cornerRadius
设置的动画品质,以及各种cornerRadius
设置在全屏星星上的样子。
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()
在 iPad 上的 Swift Playgrounds 中跑步
这可以在 iPad 上的 Swift Playgrounds 应用程序中完美运行。只需添加:
import PlaygroundSupport
在顶部和
PlaygroundPage.current.setLiveView(ContentView())
在最后。
使用 RoundedStar 形状创建欧盟标志
struct ContentView: View
let radius: CGFloat = 100
let starWidth: CGFloat = 36
let numStars = 12
var body: some View
ZStack
Color.blue
ForEach(0..<numStars) n in
RoundedStar(cornerRadius: 0)
.frame(width: starWidth, height: starWidth)
.offset(x: radius * cos(CGFloat(n) / CGFloat(numStars) * 2 * .pi), y: radius * sin(CGFloat(n) / CGFloat(numStars) * 2 * .pi))
.foregroundColor(.yellow)
【讨论】:
以上是关于如何创建 SwiftUI RoundedStar 形状?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中为 NavigationLink 创建工厂方法?