2
1

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 3 years have passed since last update.

[Swift]虹色のボーダーアニメーションを作成する

Last updated at Posted at 2021-04-18

はじめに

今回は使い所は限られるとは思いますが、虹色ボーダーラインのアニメーションを実装します。

こんな感じ↓

本編

1. 虹色のCGColor配列を作成

虹色の配列を作成します。色相、彩度、明度のうち、色相を少しずつ変化させればなだらかな虹色が作成できます。
後々のためここではUIColorではなくCGColorの配列としておきます。

var rainbow: [CGColor] {
    let increment: CGFloat = 0.02

    return [CGFloat](stride(from: 0.0, to: 1.0, by: increment)).map{ hue in 
        UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0).cgColor
    }
}

2. 虹色のグラデーションを作成する

まず虹色のグラデーションのレイヤを作成します。

グラデーションのレイヤを作成するにはCAGradientLayerを使います。
ここでCAGradientLayerのcolorsプロパティに先ほど作成した虹色の配列を適用することで、虹色グラデーションのレイヤができます。

let gradientLayer = CAGradientLayer()
gradientLayer.colors = rainbow

今回はラベルに虹色のボーダーラインアニメーションを追加しますが、そのフレームに対し少しマージンを取ります。

 gradientLayer.frame = CGRect(x: -4, y: -4, width: label.frame.width+8, height: label.frame.height+8)

グラデーションの始まりと終わりのポイントを指定します。
今回は左上から右下にかけてのグラデーションにしたいので、以下のように設定しました。この時、x,yともに0から1の範囲で指定する必要があるので注意が必要です。

gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)

こんな感じです。
スクリーンショット 2021-04-18 18.31.41.png

3. アニメーションを行うレイヤの作成

CAShapeLayerを使用します。
まずボーダラインのpathを指定します。

let shapeLayer = CAShapeLayer()
let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: label.frame.width+8, height: label.frame.height+8))
shapeLayer.path = path.cgPath

またfillColorは透明にしておきます。線の太さも決めておきます。

shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 8.0

4. maskの設定

グラデーションのレイヤにmaskとして3で作成したアニメーションを行うレイヤを設定します。
四角いグラデーションのレイヤから、maskに設定したレイヤによってくり抜くといったイメージです。

5. レイヤをviewに適用

今回はlabelに対して設定します。

label.layer.addSublayer(shapeLayer)

アニメーションの作成

CABasicAnimationを使用します。CAShapeLayerのstrokeEndプロパティを0から1までアニメーションさせたいので以下のように実装します。
また、アニメーションの時間も設定しておきます。

let animation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.strokeEnd))
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = 3.0

ここではアニメーションを無限にループさせたいので以下のように設定しておきます。

animation.repeatDuration  = .infinity

6. animationのレイヤへの適用

以下を実行するとアニメーションが始まります。

self.shapeLayer.add(animation, forKey: #keyPath(CAShapeLayer.strokeEnd))

7.完成

これで完成です。

動作原理

まず、CAGradientLayerでグラデーションのレイヤを作ります。
maskプロパティに別レイヤを設定すると、設定したレイヤの形にくり抜くことができます。
そこで、CAShapeLayerで外枠となる部分のレイヤを作成し、maskとして適用することでグラデーションの外枠ができます。
CAShapeLayerstrokeStartstrokeEndが外枠の始まりと終わりの部分を表すのでこと値をアニメーションで徐々に変化させることで、外枠がアニメーションし目的を達成することができます。

おわりに

読んでいただいてありがとうございます。初めて二日連続で記事を書きました。参考になれれば嬉しいです。
ご指摘ご質問等ございましたら、コメントまたはDMまでお願いします。
本記事での内容はこちらのリポジトリよりダウンロードできます。
簡単に実行できるので良かったら試してみてください

追記

2021/04/19

この記事に関連した記事を書きました。
合わせて読んでいただけると嬉しいです
https://qiita.com/p_x9/items/5fbe76748ee060f18daa

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?