🔴
【iOS】ColorだってKeyFrameでアニメーションさせたい
iOS 17から追加されたKeyFrameを活用することでそれぞれの値をそれぞれの時間軸で簡単にアニメーション出来るようになりました。
今回、KeyFrameについての詳細は省きますが興味を持った方はWWDC23のセッションをご覧いただければと思います。
簡単な例
アニメーションの値を定義
まずはアニメーションに使用する値を定義します。
struct AnimationValues {
var scale: CGFloat
}
keyframeAnimatorモディファイアを追加
struct CircleView: View {
var body: some View {
Circle()
.frame(width: 10, height: 10)
.keyframeAnimator(
initialValue: AnimationValues(scale: 1)
) { content, value in
content
.scaleEffect(x: value.scale, y: value.scale)
} keyframes: { _ in
KeyframeTrack(\.scale) {
CubicKeyframe(4, duration: 4)
SpringKeyframe(10, duration: 4, spring: .bouncy)
}
}
}
}
こちらの実装例では、最初の4秒間でscale
を元サイズの4倍にして、その後、4秒間でscale
を元サイズの10倍にしています。
最後の4秒間では、SpringKeyframe
を使用してスプリング関数を用いたアニメーションを実行しています。
Colorをアニメーションさせたい
アニメーションの値にColorを追加
struct AnimationValues {
var scale: CGFloat
+ var color: Color
}
keyframeAnimatorにもColorを適用
struct CircleView: View {
var body: some View {
Circle()
.frame(width: 10, height: 10)
.keyframeAnimator(
initialValue: AnimationValues(
scale: 1,
+ color: .black
)
) { content, value in
content
.scaleEffect(x: value.scale, y: value.scale)
} keyframes: { _ in
KeyframeTrack(\.scale) {
CubicKeyframe(4, duration: 4)
SpringKeyframe(10, duration: 4, spring: .bouncy)
}
+ KeyframeTrack(\.color) {
+ CubicKeyframe(.red, duration: 8)
+ }
}
}
}
ColorはAnimatableに準拠していない
すると、Color
がAnimatable
に準拠していない為、エラーが発生します。
Animatableに準拠しているタイプを使用する
Animatableのドキュメントの中にConfirming Typesという項目があり、その中にColor.Resolved
というものが準拠しているタイプとして含まれていました。
Color.Resolved
こちらもiOS 17から追加された構造体で、Color
を表す為のRBGAのセットです。
Color.Resolved is a set of RGBA values that represent a color that can be shown
引用: Color.Resolved | Apple Developer Documentation
Color.ResolvedをColorの代わりに使用する
アニメーションの値をColor.Resolvedに変更
struct AnimationValues {
var scale: CGFloat
- var color: Color
+ var color: Color.Resolved
}
keyframeAnimatorにもColor.Resolvedを適用
struct CircleView: View {
var body: some View {
Circle()
.frame(width: 10, height: 10)
.keyframeAnimator(
initialValue: AnimationValues(
scale: 1,
- color: .black
+ color: Color.black.resolve(in: .init())
)
) { content, value in
content
+ .foregroundStyle(value.color)
.scaleEffect(x: value.scale, y: value.scale)
} keyframes: { _ in
KeyframeTrack(\.scale) {
CubicKeyframe(4, duration: 4)
SpringKeyframe(10, duration: 4, spring: .bouncy)
}
KeyframeTrack(\.color) {
+ CubicKeyframe(Color.red.resolve(in: .init()), duration: 6)
+ CubicKeyframe(Color.blue.resolve(in: .init()), duration: 2)
}
}
}
}
color
の方は、6秒間かけて赤色に変化し、その後2秒間かけて青色に変化するアニメーションを付与してみました。
color
もアニメーションさせることが出来ました。
おわりに
KeyFramesのアニメーションが出来るようになり、私は非常に興奮しております。
参考
Discussion