3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swiftでやる簡単なグラフアニメーション(CABasicAnimation)

Posted at

やりたいこと

Swiftでアニメーションを作ろうと思うと毎回ググるところから始まるので自分なりにメモ
今回はsin関数のグラフを軽くアニメーションしてみます

開発環境

Xcode: 10.3
Swift: 5.0.1

とりあえず結論

ViewController.swift
class ViewController: UIViewController {

    var layer_frame = CGRect()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        layer_frame = CGRect(x: 0, y: view.frame.height/2 - 60, width: view.frame.width, height: 120)
    }
    
    @IBAction func onTouch(_ sender: Any) {
        // アニメーションを作成
        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.duration = 1.0
        animation.fromValue = 0.0
        animation.toValue = 1.0
        
        // sinグラフを描画するレイヤー
        let layer = CAShapeLayer()
        layer.frame = layer_frame
        layer.backgroundColor = UIColor.gray.cgColor
        layer.strokeColor = UIColor.cyan.cgColor
        layer.fillColor = UIColor.gray.cgColor
        layer.lineWidth = 3.0
        layer.path = create_sin_path()
        // レイヤーにアニメーションを付加
        layer.add(animation, forKey: nil)
        
        view.layer.addSublayer(layer)
    }
    
    // sin関数のCGPathを作成
    func create_sin_path() -> CGPath {
        let div: Double = 1 / 100
        let sin_path = UIBezierPath()
        let origin = CGPoint(x: layer_frame.width/2 - CGFloat(50*Double.pi), y: layer_frame.height / 2.0)
        sin_path.move(to: origin)
        for i in 0 ... Int(2.0*Double.pi / div) {
            let point_x = div * Double(i)
            let point_y = sin(point_x)
            let point = CGPoint(x: 50*point_x + Double(origin.x), y: -50*point_y + Double(origin.y))
            sin_path.addLine(to: point)
        }
        return sin_path.cgPath
    }
}

説明

1. CABasicAnimationでアニメーション処理を記述

アニメーションの方法はいくつかあるらしいけど、今回はCABasicAnimationを使ってみます。
以下のサイトが非常に参考になったので詳細を知りたい方はどうぞ。
iOSアプリ開発でアニメーションするなら押さえておきたい基礎

今回のコードでは、CABasicAnimationでstrokeEndプロパティを変化させてます。

let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 1.0    // アニメーションの時間
animation.fromValue = 0.0   // 変化させる値の初期値
animation.toValue = 1.0     // 変化させる値の終点値

2. アニメーションさせたいグラフを描画するレイヤーを作成

ここでは、グラフを描画するレイヤーを作成します。グラフの種類にもよると思うけど、今回はUIBezierPathでグラフを作成するので、レイヤーはCAShapeLayerを使います。
UIBezierPathとCAShapeLayerの使い方は以下のサイトが参考になりました。
Swiftで描画し、アニメーションするまでのメモ

CAShapeLayerのpathプロパティに描画したいグラフのCGPath(UIBezierPath)を設定すればOKです。また、strokeColorプロパティでは線の色を指定できます。

let layer = CAShapeLayer()
layer.frame = layer_frame                       // 位置、サイズを指定
layer.backgroundColor = UIColor.gray.cgColor    // 背景
layer.strokeColor = UIColor.cyan.cgColor        // 線の色
layer.fillColor = UIColor.gray.cgColor          // 図形(グラフ)の内側の色?(グラフを描画するならbackgroundColorと同じのほうがいいかも?)
layer.lineWidth = 3.0                           // 線の太さ
layer.path = create_sin_path()                  // 描画する図形(グラフ)

その他のプロパティについては公式ドキュメントで詳細が分かると思います。
CAShapeLayer - Core Animation | Apple Developer Documentation

グラフの作成

create_sin_path()でsin関数のグラフを作成してます。細かい説明は省きますが、UIBezierPathでsin関数のx座標とy座標を線で繋げているだけです。
正直、ただの一本線でもアニメーションは確認できるのでsin関数にする必要ななかったですねw。

3. 作成したレイヤーにアニメーションを追加する

先ほど、作成したレイヤーにアニメーション処理を追加します。
以下のコードの部分ですね

layer.add(animation, forKey: nil)

最後にレイヤーを表示されているViewのlayerのsublayerとして追加すれば完成です。

view.layer.addSublayer(layer)

今回は、ViewController内にあるViewのlayerに追加しました。

結果

ezgif-1-bd969d2f38e9.gif

できましたね!
今回は単純なアニメーションだったので少ないコードで書けましたが、もっと複雑なアニメーションも作れるようになりたいものですね...。

参考サイト

iOSアプリ開発でアニメーションするなら押さえておきたい基礎
Swiftで描画し、アニメーションするまでのメモ
CAShapeLayer - Core Animation | Apple Developer Documentation

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?