💃

【iOS】Coreで踊らにゃ損!踊らにゃ損です

2024/04/29に公開

はじめに

出オチです

最近少しCoreAnimationの勉強をしたので、自分のキャラクターを踊らせたいなと思ってやりました

https://developer.apple.com/documentation/quartzcore

CoreAnimationとは?

CoreAnimationとはフレーム単位でアニメーションする内容を設定できる仕組みです。
フレーム単位で設定することで様々なアニメーションがiOSアプリ上で実現できます。

UIView.animateでは実現できないな〜と思ってるアニメーションの多くは大体CoreAnimationで実現できます

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004514

UIImageViewの初期化

まず、UIImageView のインスタンスを2つ作成し、それぞれの位置、サイズ、およびコンテンツモードを設定します。また、画像を読み込み、ビューに追加します。

import UIKit

class CoreAnimationViewController: UIViewController {

    let dancingImageView = UIImageView()
    let backGroundDancingImageView = UIImageView()

    override func viewDidLoad() {
        super.viewDidLoad()

        setupImageViews()
    }

    private func setupImageViews() {
        dancingImageView.frame = CGRect(x: 150, y: 200, width: 100, height: 100)
        dancingImageView.contentMode = .scaleAspectFit
        backGroundDancingImageView.frame = CGRect(x: 150, y: 200, width: 100, height: 100)
        backGroundDancingImageView.contentMode = .scaleAspectFit
        backGroundDancingImageView.tintColor = .black

        if let image = UIImage(named: "entakun") {
            dancingImageView.image = image
            backGroundDancingImageView.image = image.withRenderingMode(.alwaysTemplate)
        }

        view.addSubview(backGroundDancingImageView)
        view.addSubview(dancingImageView)
    }
}

アニメーションの定義と適用

画像に「ダンス」アニメーション(回転と上下移動)を適用し、別のアニメーションとして円運動を設定します。これらは viewDidAppear メソッド内で実行されます。

ダンスアニメーションの追加

ダンスアニメーションでは左右に振るアニメーションと上下にフルアニメーションを細かく分けています。
このように複数のアニメーションをCoreAnimationで組み合わせることで踊っているような動きを実現します。


func animateDance() {
    let rotationAnimation = createRotationAnimation()
    let verticalAnimation = createVerticalAnimation()

    let group = CAAnimationGroup()
    group.animations = [rotationAnimation, verticalAnimation]
    group.duration = 0.6
    group.repeatCount = Float.infinity
    dancingImageView.layer.add(group, forKey: "dancing")
}

private func createRotationAnimation() -> CAKeyframeAnimation {
    let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
    rotationAnimation.values = [0, 0.05, 0, -0.05, 0]  // 左右に振る
    rotationAnimation.duration = 0.15
    rotationAnimation.repeatCount = Float.infinity
    return rotationAnimation
}

private func createVerticalAnimation() -> CAKeyframeAnimation {
    let verticalAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y")
    verticalAnimation.values = [0, -1, 0, 1, 0]  // 上下に振る
    verticalAnimation.duration = 0.2
    verticalAnimation.repeatCount = Float.infinity
    return verticalAnimation
}

円運動アニメーションの追加

画像の奥にある影の部分で同じ動きをすると全く見えなくなってしまうので、円運動アニメーションを行い動きに躍動感をつけます。

func animateCircularMotion() {
    let circularPath = UIBezierPath(arcCenter: CGPoint(x: 200, y: 250), radius: 3, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: false)
    let circularMotion = CAKeyframeAnimation(keyPath: "position")
    circularMotion.path = circularPath.cgPath
    circularMotion.duration = 0.6
    circularMotion.repeatCount = .infinity
    circularMotion.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    backGroundDancingImageView.layer.add(circularMotion, forKey: "circularMotion")
}

https://github.com/entaku0818/AudioMaster/blob/main/AudioMasterApp/AudioMasterApp/AudioMasterApp/AVF/CoreAnimationViewController.swift
ここまでのサンプルコードをこちらで確認できます。

まとめ

この記事では、UIImageView に複数のアニメーションを組み合わせて適用する方法を解説しました。CoreAnimation の機能をフルに活用することで、iOSアプリのUIにダイナミックで魅力的な動きを加えることができます。

Discussion