[iOS] カウントダウンビューを作ってみました

2016.12.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

映画のフィルムなどで、始まる前にカウントダウンするあのイメージ。(伝わらない?)

あれを表示したかったのですが、UIKitのアニメーションでは、ちょっと無理のようだったので、UIBezierPathCABasicAnimationで表現しました。 本記事は、その作業の纏めです。

最初に、作ってみたカウントダウンです。

001

2 UIBezierPath

(1) インスタンス生成

UIBezierPathは、直線や曲線などを描画できる、描画用のクラスです。 今回は、これを使用して円を描画しました。

let center = CGPoint(x: x, y: y) // 中心座標
let radius = bounds.size.width / 2.0 - lineWidth / 2 // 半径は、Viewの半分
let startAngle = CGFloat(-M_PI_2) // 開始位置は、上
let endAngle = startAngle + 2.0 * CGFloat(M_PI) // 開始位置から360°
let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)

(2) CAShapeLayer

通常このUIBezierPathは、drawPointをオーバライドして、その中で使用されますが、それではアニメーションができません。

アニメーションにさせるためには、CAShapeLayerを作成し、そのpathプロパティにセットし、後述するCABasicAnimationでアニメーションさせます。

let shapeLayer = CAShapeLayer()

shapeLayer.frame = CGRect(x: 0, y: 0, width: width, height: height) //サイズ
shapeLayer.strokeColor = lineColor.cgColor // 先の色
shapeLayer.lineWidth = lineWidth // 先の太さ

shapeLayer.path = path.cgPath // UIBezierPathをセットする
layer.addSublayer(shapeLayer) // UIViewのlayerにセットする

3 CABasicAnimation

(1) インスタンス生成

CABasicAnimationを使用することで基本的なキーフレームアニメーションを行うことができます.

キーフレームアニメーションとは、キーパスを登録し、アニメーションの開始と終了を指定することで中間を計算させて作るアニメーションです。

CAShapeLayerstrokeEndプロパティは、円の線描画をする際の、停止位置を0.0〜1.0の値で指定するものです。 ここでは、このstrokeEndプロパティに対してアニメーションを設定しています。

let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 0.8 // アニメーション時間
animation.fromValue = 0.0 // 開始
animation.toValue = 1.0 // 終了
shapeLayer.add(animation, forKey: "circleAnim") // アニメーション開始

(2) 通知

CABasicAnimationのdelegateをセットすることで、アニメーションの開始と終了時に通知を受け取ることが出来ます。

animation.delegate = self

そして、自身が、UIViewの場合は、この通知を受け取るためには、 CAAnimationDelegateプロトコルを実装する必要があります。

class CountDownView: UIView, CAAnimationDelegate {
  //
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    // アニメーションの終了
}

func animationDidStart(_ anim: CAAnimation){
    // アニメーションの開始
}

(3) 停止

removeAnimationを使用して、アニメーションを中断させることができます。

shapeLayer.removeAnimation(forKey: "circleAnim")

4 最後に

今回は、簡単な、カウントダウンビューを作成してみました。 現在、これを色付けすることで、色々な雰囲気のカウントダウンが作れないかと画策中です。

コードは下記に置きました。気になるところが有りましたら、ぜひ教えてやってください。
github [GitHub] https://github.com/furuya02/CountDownView

5 参考資料


UIBezierPathにCABasicAnimationでアニメーションをつける
API Reference CABasicAnimation
API Reference UIBezierPath
API Reference CAShapeLayer