UIViewを曲線上にアニメーションさせる方法
今回は半径分だけアニメーションさせて見ます。
まずは全コードを。。
開発環境:Xcode8 + swift3
スタートボタンのイベントはIBかストーリーボードで設定して繋げてください。
import UIKit class CurveAnimationViewController: UIViewController { let animateView: UIView = UIView() let viewSize: CGFloat = 100.0 let curcleRadius: CGFloat = 150.0 let duration: TimeInterval = 0.5 var isDownView: Bool = false override func viewDidLoad() { super.viewDidLoad() animateView.frame = CGRect(x: (UIScreen.main.bounds.width / 2) - (viewSize / 2), y: UIScreen.main.bounds.height / 2 - viewSize / 2, width: viewSize, height: viewSize) animateView.layer.cornerRadius = viewSize / 2.0 animateView.backgroundColor = UIColor.orange self.view.addSubview(animateView) } @IBAction func tappedStartButton(_ sender: UIButton) { isDownView = !isDownView if isDownView { self.downAnimation() }else{ self.upAnimation() } } } //MARK: - animation extension CurveAnimationViewController { func downAnimation() { animateView.layer.removeAnimation(forKey: "end") let animation: CAKeyframeAnimation = self.animation() let path: CGMutablePath = CGMutablePath() let startPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: animateView.frame.minY + (animateView.frame.height / 2.0)) let midPoint: CGPoint = CGPoint(x: startPoint.x + curcleRadius, y: startPoint.y + curcleRadius / 2.0) let endPoint: CGPoint = CGPoint(x: startPoint.x, y: startPoint.y + curcleRadius) path.move(to: startPoint) path.addQuadCurve(to: endPoint, control: midPoint) animation.path = path animateView.layer.add(animation, forKey: "start") } func upAnimation() { animateView.layer.removeAnimation(forKey: "start") let animation: CAKeyframeAnimation = self.animation() let path: CGMutablePath = CGMutablePath() let startPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: animateView.frame.minY + (animateView.frame.height / 2.0) + curcleRadius) let midPoint: CGPoint = CGPoint(x: startPoint.x + curcleRadius, y: startPoint.y - curcleRadius / 2.0) let endPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: startPoint.y - curcleRadius) path.move(to: startPoint) path.addQuadCurve(to: endPoint, control: midPoint) animation.path = path animateView.layer.add(animation, forKey: "end") } func animation() -> CAKeyframeAnimation { let animation: CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position") animation.fillMode = kCAFillModeForwards animation.isRemovedOnCompletion = false animation.duration = duration return animation } }
詳しく説明をしていきます。
今回はUIViewをアニメーションさせるためにCAKeyframeAnimation
を使用しています。
func animation() -> CAKeyframeAnimation
内で設定している内容は下記の通りです。
CAKeyframeAnimation | 説明 |
---|---|
fillMode | アニメーションの再生中もしくは再生後のスタイル。 プロパティについてはこちらのサイトがわかりやすくまとめていました。【iOS Swift アニメーション入門 #4】Core AnimationのfillModeプロパティ | Swift,Objective-Cプログラミング ~ iOS ~ |
isRemovedOnCompletion | アニメーション完了時に、ターゲットのレイヤーからアニメーションを削除するかどうかを設定。デフォルトはYes |
duration | アニメーションの長さ。 |
このCAKeyframeAnimationに作成したパスを入れて、動かしたいUIViewのレイヤーに加えてあげればアニメーションが開始されます。
では、パスをどのように設定しているか見ていきしょう。
let path: CGMutablePath = CGMutablePath() //出発地点 > 動かしたいViewのセンターを計算しています。 let startPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: animateView.frame.minY + (animateView.frame.height / 2.0) + curcleRadius) //中間地点 > 出発地点と最終地点の真ん中の位置を計算します。 let midPoint: CGPoint = CGPoint(x: startPoint.x + curcleRadius, y: startPoint.y - curcleRadius / 2.0) //最終地点 > 最終地点のポジション。 let endPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: startPoint.y - curcleRadius) //出発地点のポイントを設定します。 path.move(to: startPoint) //最終地点と中間地点を設定します。 path.addQuadCurve(to: endPoint, control: midPoint) //先ほどのCAKeyframeAnimationにパスを設定。 animation.path = path //UIViewにCAKeyframeAnimationを追加。 animateView.layer.add(animation, forKey: "start")
pathの数値を変えるなどして試して見てください。
特に難しい計算を必要とせずに、どこに向かってアニメーションさせたいかのポイントを入れるだけなので、とても簡単に実装できます。