- iOS
- 2017-06-09 - 更新:2018-02-15
今回はUIViewやUIButtonをアニメーションさせる方法をご紹介します。
まずはアニメーションさせる適当なViewを作成します。
let sampleView = UIView() sampleView.frame.size = CGSize(width: 120, height: 120) sampleView.center = CGPoint(x: 60, y: 60) sampleView.backgroundColor = UIColor.white sampleView.layer.borderColor = UIColor.cyan.cgColor sampleView.layer.borderWidth = 2 view.addSubview(sampleView)
作成したViewをアニメーションさせるにはUIView.animateメソッドを使用します。
ここでは大きさを変更してみましょう。
中心点も設定しているのは、大きさを変更すると左上を起点に大きさが変わってしまうためです。
UIView.animate(withDuration: 0.5, animations: { self.sampleView.frame.size = CGSize(width: 80, height: 80) self.sampleView.center = CGPoint(x: 60, y: 60) }, completion: { Void in // アニメーション完了時の処理を記述します })
次に、大きさと角丸の半径をアニメーションで変更してみたいと思います。
サンプルとして、標準カメラアプリの動画撮影ボタンのようなボタンを作成してみましょう。
実際の撮影処理はしていません。
まずは必要な宣言
let shutterView = UIView() let shutterButton = UIButton() var isRecording: Bool = false
Viewを作成するメソッドを作成します。
func makeShutterView() { shutterView.frame.size = CGSize(width: 74, height: 74) shutterView.center = CGPoint(x: 45, y: 45) let shutterCircle = UIView() shutterCircle.frame.size = CGSize(width: 76, height: 76) shutterCircle.center = CGPoint(x: 45, y: 45) shutterCircle.layer.borderColor = UIColor.white.cgColor shutterCircle.layer.borderWidth = 4 shutterCircle.layer.cornerRadius = 38.0 shutterView.addSubview(shutterCircle) shutterButton.frame.size = CGSize(width: 60, height: 60) shutterButton.center = CGPoint(x: 45, y: 45) shutterButton.backgroundColor = UIColor.red shutterButton.layer.cornerRadius = 30.0 shutterButton.addTarget(self, action: #selector(onClickRecordingButton), for: .touchUpInside) shutterView.addSubview(shutterButton) view.addSubview(shutterView) }
次にボタンを押した時に実行されるメソッドです。
isRecordingをフラグとして動画の撮影開始・停止を判別しています。
func onClickRecordingButton(sender: UIButton) { if isRecording { isRecording = false stopRecoding() } else { isRecording = true startRecording() } }
撮影開始のメソッド
※アニメーションについて別の書き方をしていますが動作は同じです。
サイズを小さくして少し角の丸い停止ボタンに変形させます。
func startRecording() { UIView.beginAnimations(nil, context: nil) UIView.setAnimationDuration(0.2) // アニメーション時間 shutterButton.frame.size = CGSize(width: 40, height: 40) shutterButton.center = CGPoint(x: 45, y: 45) // 角丸半径のアニメーション shutterButtonCRAnimation(layer: shutterButton.layer, corner: 8.0, duration: 0.2) UIView.commitAnimations() }
撮影停止のメソッド
元のサイズ・形に戻します。
func stopRecoding() { UIView.beginAnimations(nil, context: nil) UIView.setAnimationDuration(0.3) // アニメーション時間 shutterButton.frame.size = CGSize(width: 60, height: 60) shutterButton.center = CGPoint(x: 45, y: 45) // 角丸半径のアニメーション shutterButtonCRAnimation(layer: shutterButton.layer, corner: 30.0, duration: 0.3) UIView.commitAnimations() }
アニメーションに遅延を発生さたい場合はUIView.setAnimationDelay(1.3)
等とします。
お気づきかもしれませんが、shutterButton.layer.cornerRadiusについては別メソッドでアニメーションさせています。
これはUIView.animateでは角丸半径のアニメーションをさせることが出来ないからです。
UIView.animateでアニメーションさせることが出来るのは以下の通り。
frame | ビューの位置とサイズ |
bounds | ビューのサイズ |
center | ビューの位置 |
transform | ビューへの変形処理 |
alpha | ビューの透過度 |
backgroundColor | ビューの背景色 |
contentStretch | ビュー上のコンテンツのストレッチ方法 |
UIView.animateでアニメーションさせることが出来ないものは、Core Animationでアニメーションさせる必要があります。
以下が角丸半径をアニメーションさせる方法になります。
func shutterButtonCRAnimation(layer: CALayer, radius: CGFloat, duration: CFTimeInterval) { let crAnimation = CABasicAnimation(keyPath: "cornerRadius") crAnimation.toValue = radius crAnimation.fromValue = layer.cornerRadius crAnimation.duration = duration // アニメーション時間 layer.add(crAnimation, forKey: nil) layer.cornerRadius = radius // 終了時に元に戻ってしまわないようにします }
また、以下のメソッドを使えばイーズインやバウンドするアニメーションを作成することも可能です。
UIView.animate(withDuration: <TimeInterval>, delay: <TimeInterval>, options: <UIViewAnimationOptions>, animations: <() -> Void>, completion: <((Bool) -> Void)?>) UIView.animate(withDuration: <TimeInterval>, delay: <TimeInterval>, usingSpringWithDamping: <CGFloat>, initialSpringVelocity: <CGFloat>, options: <UIViewAnimationOptions>, animations: <() -> Void>, completion: <((Bool) -> Void)?>)
例えば以下のような感じです。
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn, animations: { shutterButton.frame.size = CGSize(width: 60, height: 60) shutterButton.center = CGPoint(x: 45, y: 45) }, completion: nil)
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 20, options: .curveLinear, animations: { shutterButton.frame.size = CGSize(width: 60, height: 60) shutterButton.center = CGPoint(x: 45, y: 45) },completion: nil)
usingSpringWithDampingは基本値が「1」で値が小さくなるほど終点でバウンドする幅が大きくなるそうです。
initialSpringVelocityについてはよくわからないのですが、flashで良くあった揺れのようなものでしょうか。
ちなみに録画開始と停止の音を出すならサウンドIDは1117と1118です。
音を鳴らす方法はこちらをご参照ください。
Xcode: 8.3.3
Swift: 3.1
OS: Sierra 10.12