この記事で分かることは?
以下のようなShapeを使った円などのアニメーションを実現する方法がわかります。

Shapeのアニメーション化とは?
Shapeによる円などの実現方法に関しては以下で記載しているのでご参照下さい。
Shapeは元々Animatableプロトコルを継承しています。そのため以下のanimatableDataを持っています。
var animatableData: EmptyAnimatableData
このanimatableDataにアニメーションさせたい変数をセットすることで、その変数はアニメーションします。
以下はendAngleをアニメーション化したい場合
var endAngle:Double
var animatableData: Double{
get{endAngle}
set{endAngle = newValue}
}
例:円のアニメーション
上記で示したanimatableDataを円の終点として、下部のボタンを押すと終点がランダムで決まるソフト(冒頭のGIF)のソースが以下となります。
struct Arc:Shape{
var startAngle:Double
var endAngle:Double
var clockwise:Bool
var animatableData: Double{
get{endAngle}
set{endAngle = newValue}
}
func path(in rect: CGRect) -> Path {
let rotationAdjustment = Angle(degrees: 90)
let modifiedStart = Angle(degrees: startAngle) - rotationAdjustment
let modifiedEnd = Angle(degrees: endAngle) - rotationAdjustment
var path = Path()
path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.width / 2, startAngle: modifiedStart, endAngle: modifiedEnd, clockwise: clockwise)
path.addLine(to: CGPoint(x: rect.midX, y: rect.midY))
path.closeSubpath()
return path
}
}
struct ContentView: View {
@State private var endAngle = 90.0
var body: some View {
VStack{
Arc(startAngle: 0.0, endAngle: endAngle, clockwise: false)
Button {
withAnimation {
endAngle = Double.random(in: 0..<360)
}
} label: {
Text("Start")
}
}
}
}

注意点
animatableDataに直接Angleは入れられない
最初Angleを入れてハマりましたがDoubleでないといけないようです。自分の理解では。
詳細は公式をみてください。
Apple Developer Documentation
withAnimationだけでも動きそうですがanimatableDataを使わないとアニメーションしません。
これはその通りで一見Shapeで使う変数に対してwitAnimationだけでも動く気がしてしまうのですが、動きません。
さいごに
アニメーションの確認は楽しいです。Shapeでは様々な図形が書けますので色々試して頂ければ幸いです。
SwiftUIのおすすめ参考書籍
図とサンプルコードが多くわかりやすく、手を動かしながら学べるのはもちろんですが、状態やデータフローに関する解説や、swiftuiから uikitを使う方法、uikitから swiftuiを使う方法などフレームワークの関連性まで説明していてとても参考になります。
コメント