介绍
边制作边学习!动画指示符版本。
完成后,动画将如下所示。
让我们做
圈一个
首先,制作一个基圆。
1 2 3 4 5 6 7 | import SwiftUI struct ContentView: View { var body: some View { Circle() } } |
挖出一个圆圈以制成戒指
使用
圆。
1 2 3 4 | func stroke(S, lineWidth: CGFloat) -> View func stroke(S, style: StrokeStyle) -> View func stroke(lineWidth: CGFloat) -> Shape func stroke(style: StrokeStyle) -> Shape |
https://developer.apple.com/documentation/swiftui/shape
您可以指定颜色,例如"颜色"和"渐变"以及颜色渐变。
https://developer.apple.com/documentation/swiftui/shapestyle
首先,将颜色设为绿色以便于理解。
1 2 3 4 5 6 | struct ContentView: View { var body: some View { Circle() .stroke(Color.green) } } |
这会使线变细且难以看清,因此加宽线使其更容易看清。
为此,我们将应用
描边样式
一个对象,用于定义边框或分隔线的颜色,宽度和样式。
https://developer.apple.com/documentation/apple_news/strokestyle
1 2 3 4 5 6 | StrokeStyle(lineWidth: CGFloat, lineCap: CGLineCap, lineJoin: CGLineJoin, miterLimit: CGFloat, dash: [CGFloat], dashPhase: CGFloat) |
lineWidth
线宽默认为1
由于它是
,因此将
1 2 3 4 5 6 | struct ContentView: View { var body: some View { Circle() .stroke(Color.green, style: StrokeStyle(lineWidth: 8)) } } |
如果它仍然是
圆,则即使旋转它也不知道,因此请使用
trim(from:to:)
1 | func trim(from startFraction: CGFloat = 0, to endFraction: CGFloat = 1) -> some Shape |
https://developer.apple.com/documentation/swiftui/shape/3365372-trim
1 2 3 4 5 6 7 | struct ContentView: View { var body: some View { Circle() .trim(from: 0, to: 0.4) .stroke(Color.green, style: StrokeStyle(lineWidth: 8)) } } |
如果原样保留圆,则圆会很大,因此请使用
1 2 3 4 5 6 7 8 9 10 | import SwiftUI struct ContentView: View { var body: some View { Circle() .trim(from: 0, to: 0.6) .stroke(Color.green, style: StrokeStyle(lineWidth: 8)) .frame(width: 48, height: 48) } } |
它变成了指示器大小!
尖角将变为圆形。
为此,请使用
CGLineCap(iOS 2.0)
<表格>
tr>
header>
<身体>
td>tr>
td>tr>
td>tr>
tbody>
table>
https://developer.apple.com/documentation/coregraphics/cglinecap
1 2 3 4 5 6 7 8 9 | struct ContentView: View { var body: some View { Circle() .trim(from: 0, to: 0.6) .stroke(Color.green, style: StrokeStyle(lineWidth: 8, lineCap: .round)) .frame(width: 48, height: 48) } } |
CGLineJoin(iOS 2.0)
如果图形有角,则可以看到更改,如下所示。
但是,由于这次创建的指示器是弧形的,因此请使其顺畅流动。
<表格>
tr>
header>
<身体>
td>
td>
td>tr>
tbody>
table>
miterLimit
将
dash
将虚线的形状指定为数组。
1 | [線の長さ, 空白の長さ, 2番目の線の長さ, 2番目の空白の長さ, ...] |
1 2 3 4 5 6 7 8 9 10 11 12 | struct ContentView: View { var body: some View { Circle() .trim(from: 0, to: 0.4) .stroke(Color.green, style: StrokeStyle( lineWidth: 8, lineCap: .round, dash: [0.1, 16])) .frame(width: 48, height: 48) } } |
dashPhase
更改虚线的开始位置。默认值为0
让我们旋转
终于是动画了。
将
rotationEffect(_:anchor:)
1 | func rotationEffect(_ angle: Angle, anchor: UnitPoint = .center) -> some View |
https://developer.apple.com/documentation/swiftui/text/3276966-rotationeffect
对于
对于
angular
https://developer.apple.com/documentation/swiftui/angle
您可以将
由于这次将传递angular,因此我们将
1 2 3 4 5 6 7 8 9 10 11 12 13 | struct ContentView: View { var body: some View { Circle() .trim(from: 0, to: 0.6) .stroke(Color.green, style: StrokeStyle( lineWidth: 8, lineCap: .round, dash: [0.1, 16])) .frame(width: 48, height: 48) .rotationEffect(Angle(degrees: 180)) } } |
围绕中心旋转180度。
但这不是动画。
因此,我们将尝试随着时间的推移对其进行更改。
onAppear
首先,确定动画何时触发。
有各种各样的事情,例如按下按钮,滚动等,但是这次我将制作显示目标View的动画。
因此,请使用onAppear方法。
1 | func onAppear(perform action: (() -> Void)? = nil) -> some View |
使用View时,调用此方法将执行操作关闭。
https://developer.apple.com/documentation/swiftui/text/3276931-onappear
接下来是基本的动画处理。
这次,我们将使用
withAnimation
用指定的动画更新视图。
https://developer.apple.com/documentation/swiftui/3279151-withanimation
将要更改的状态变量与动画一起传递给闭包。
动画
<表格>
tr>
header>
<身体>
td>tr>
td>tr>
td>tr>
td>tr>
td>tr>
tbody>
table>
这一次,我希望您保持恒定的速度旋转,所以我将使用
您可以在
lienar方法中指定动画长度。
使用
@状态
设置状态变量。
通过在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | struct ContentView: View { @State var isAnimation = false var body: some View { Circle() .trim(from: 0, to: 0.6) .stroke(Color.green, style: StrokeStyle( lineWidth: 8, lineCap: .round, dash: [0.1, 16])) .frame(width: 48, height: 48) .rotationEffect(Angle(degrees: self.isAnimation ? 360 : 0)) .onAppear() { withAnimation( Animation .linear(duration: 1)) { self.isAnimation.toggle() } } } } |
如果保持原样,则只能旋转一次结束,因此请使用
repeatForever(autoreverses:)
https://developer.apple.com/documentation/swiftui/animation/3263783-repeatforever
<表格>
tr>
header>
<身体>
td>tr>
td>tr>
tbody>
table>
指定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | struct ContentView: View { @State var isAnimation = false var body: some View { Circle() .trim(from: 0, to: 0.6) .stroke(Color.green, style: StrokeStyle( lineWidth: 8, lineCap: .round, dash: [0.1, 16])) .frame(width: 48, height: 48) .rotationEffect(Angle(degrees: self.isAnimation ? 360 : 0)) .onAppear() { withAnimation( Animation .linear(duration: 1) .repeatForever(autoreverses: true)) { self.isAnimation.toggle() } } } } |
圆角矩形
等级
1 | Gradient(colors: [.gray, .white]) |
<表格>
tr>
header>
<身体>
td>tr>
td>tr>
td>tr>
tbody>
table>
将
然后,您可以确认虚线的位置已如下图所示移动。
然后更改
通过设置
画得很漂亮。
完成的源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import SwiftUI struct ContentView: View { @State var isAnimation = false var body: some View { ZStack { RoundedRectangle(cornerRadius: 8) .frame(width: 200, height: 120, alignment: .center) .foregroundColor(Color.gray) VStack { Spacer() Circle() .trim(from: 0, to: 0.6) .stroke(AngularGradient(gradient: Gradient(colors: [.gray, .white]), center: .center), style: StrokeStyle( lineWidth: 8, lineCap: .round, dash: [0.1, 16], dashPhase: 8)) .frame(width: 48, height: 48) .rotationEffect(Angle(degrees: self.isAnimation ? 360 : 0)) .onAppear() { withAnimation( Animation .linear(duration: 1) .repeatForever(autoreverses: false)) { self.isAnimation.toggle() } } Text("読み込み中") .foregroundColor(.white) .font(.system(size: 12, weight: .medium, design: .rounded)) .lineLimit(1) .padding(.top) Spacer() } } } } |
挑战
我无法在strokestyke的破折号上击中动画;;
我想更改短划线的宽度,并使用easyOut制作动画,每个球都在动画的结尾附近以制作动画;;
请告诉我mm