[iOS] Animation 방법(UIView.animate)

728x90

 

iOS에서 자주 사용하는 애니메이션은 크게 2가지가 존재합니다.

  1. UIKit을 이용한 UIView의 API
  2. Core Animation을 이용한 API

이번 포스트에선 1번 UIView의 API에 대한 기본 사용법, Spring애니메이션, 여러가지 애니메이션 옵션들에 대해 알아 보도록 하겠습니다.

 

iOS 2부터 절차적으로 사용되던 애니메이션(beginAnimations, commitAnimations)은 iOS13에서 deprecated되었고,

iOS 4부터는 Closure형태인 animate메서드를 주로 이용해왔습니다.

 

하지만! 여전히 많이~ 사용되고 있지만 이 메서드도 언젠간 deprecated될 것 같습니다.

💡 Use of these methods is discouraged. Use the UIViewPropertyAnimator class to perform animations instead.

 

공식 문서에는 UIViewPropertyAnimator사용을 권장하고 있습니다.

UIViewPropertyAnimator는 iOS 10이상 부터 사용 가능한 API입니다.

아직은 amimate를 많이 사용하기 때문에 UIViewPropertyAnimator는 다음 포스트에서 알아보도록 하겠습니다!

 

Animate


특징

  • Closure 기반

  • 애니메이션이 동작하는 동안 user interaction은 일시적으로 disabled

  • 애니메이션이 가능한 속성

    → frame, bounds, center, transfrom, alpha, backgroundColor

     

구현 방법

  • animate(withDuration:animations:)

duration, animations의 파라미터로 받는 애니메이션의 기본 메서드

class func animate(
  withDuration duration: TimeInterval,
  animations: @escaping () -> Void
)

 

  • animate(withDuration:animations:completion:)

duration, animations의 파라미터로 받는 애니메이션의 기본 메서드의 애니메이션이 완료되면 completion이 동작하는 메서드

class func animate(
  withDuration duration: TimeInterval, 
  animations: @escaping () -> Void, 
  completion: ((Bool) -> Void)? = nil
)

 

2초 동안 origin과 size를 애니메이션을 구현하는 간단한 코드

var object = CGRect(x: 50, y: 150, width: 50, height: 50)

UIView.animate(withDuration: 2.0, animations: {
  // duration동안(2초)의 애니메이션이 동작하는 구간
  // 좌표(50, 150), size(50)에서 (100, 400), size(200)으로 2초간 애니메이션을 해라!
  object.frame = CGRect(x: 100, y: 400, width: 200, height: 200)
}, completion: { finished in
  // druration동안(2초)의 애니메이션이 끝나고 나서 동작하는 구간
})

 

  • 해제 방법

이러한 애니메이션을 동작이 있으니 해제하는 방법에 대해서도 알아보도록 하겠습니다.

layer에 접근해 animation을 remove시켜주면 애니메이션을 해제할 수 있습니다.

// 애니메이션을 제거 하는 방법
object.layer.removeAllAnimations()

 

위의 내용을 활용한 토글 버튼을 이용해서 애니메이션을 동작시키면 사각형의 object가 크기가 늘어났다 원래 자리로 되돌아가는 형태의 기본 애니메이션의 예제를 확인 해보록 하겠습니다.

  • 전체 예제

 

 

/*
  1초 동안 animations의 클로저가 동작하고 애니메이션이 끝나면 completion이 동작하는 로직
*/

import UIKit

class ViewController: UIViewController {

  @IBOutlet weak var object: UIView!
  @IBOutlet weak var animationToggle: UISwitch!

  override func viewDidLoad() {
    super.viewDidLoad()
    reset()
  }

  @IBAction func animationToggle(_ sender: UISwitch) {
    sender.isOn ? start() : reset()
  }

  private func start() {
    var frame = object.frame
    frame.origin = CGPoint(x: 100, y: 400)
    frame.size = CGSize(width: 200, height: 200)

    UIView.animate(withDuration: 1.0, animations: {
      //하나만 가능한게 아니고 동시에 여러개의 속성의 애니메이션이 가능하다.
      self.object.frame = frame
      self.object.alpha = 0.5
      self.object.backgroundColor = .magenta
    }, completion: { finished in
      UIView.animate(withDuration: 1.0) {
        self.reset()
      }
    })
  }

  private func reset() {
    object.frame = CGRect(x: 50, y: 150, width: 50, height: 50)
    object.alpha = 1.0
    object.backgroundColor = UIColor.yellow
  }

}

 

 

Spring 애니메이션


UIView.animate에는 여러 가지 애니메이션 옵션을 줄 수 있습니다.

그 중에서 스프링의 효과와 관련된 애니메이션에 대해 알아보도록 하겠습니다.

 

구현 방법

  • animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)

usingSpringWithDamping, initialSpringVelocity(스프링 속도), 여러가지 애니메이션을 제공하는 options을

파라미터로 받는 애니메이션입니다.

 

 

class func animate(
	withDuration duration: TimeInterval, 
	delay: TimeInterval, 
	usingSpringWithDamping dampingRatio: CGFloat, 
	initialSpringVelocity velocity: CGFloat, 
	options: UIView.AnimationOptions = [], 
	animations: @escaping () -> Void, 
	completion: ((Bool) -> Void)? = nil
)

usingSpringWithDamping은 스프링 애니메이션이 정지 상태(= 애니메이션이 끝나갈때)에 근접할 때의 damping 비율을 말합니다.

0.0 ~ 1.0 까지의 값을 가지고 있고, 0에 가까울 수록 심하게 damping이 됩니다.

 

initialSpringVelocity는 스프링의 속도를 말합니다.

0.0 ~ 1.0까지의 값을 가지고 있고, 0에 가까울 수록 스프링의 속도가 빠릅니다.

 

  • 예제)
private func start() {
	UIView.animate(withDuration: 2.0,
                 delay: 0,
                 usingSpringWithDamping: 0.2,
                 initialSpringVelocity: 0.2,
                 options: .curveEaseInOut,
                 animations: {
      self.object.frame = CGRect(x: 100, y: 400, width: 200, height: 200)
      self.object.alpha = 0.5
      self.object.backgroundColor = .magenta
    }, completion: nil)
}

 

 

옵션에 따른 다양한 애니메이션


UIView.AnimationOptions

 

UIView.AnimationOptions - UIView | Apple Developer Documentation

Specify an ease-in ease-out curve, which causes the animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing.

developer.apple.com

다양한 옵션들이 존재하지만, 자주 사용되는 옵션들에 대해 알아보도록 하겠습니다.

이러한 옵션들은 배열을 통해서 동시에 사용 가능합니다.

 

💡 접두어로 transition~ 인 옵션은 UIView.animate가 아닌 UIView.transition을 이용해야됩니다.

 

  • static var allowUserInteraction: UIView.AnimationOptions
    • 애니메이션중에는 터치 이벤트가 disable되는데, 터치 이벤트를 활성화하고 싶을때 사용하는 옵션.
  • static var repeat: UIView.AnimationOptions

    • 무한정으로 애니메이션을 반복하고싶을때 사용하는 애니메이션

  • static var autoreverse: UIView.AnimationOptions

    • 애니메이션을 반대로도 실행할 수 있게 해주는 옵션(repeat과 함께 사용해야 함)

 

예제)

UIView.animate(withDuration: 1.0,
                   delay: 0,
                   options: [.repeat, .autoreverse],
                   animations: {
      self.object.frame = CGRect(x: 100, y: 400, width: 200, height: 200)
      self.object.alpha = 0.5
      self.object.backgroundColor = .magenta
}, completion: nil)

 

 

위에서 봤던 예제처럼 completion handler로 원래의 위치로 돌아가는 로직을 추가하지 않아도, repeatautoreverse를 통해서 구현이 가능합니다!

  • static var curveEaseInOut: UIView.AnimationOptions

    • 기본값

    • 천천히 진행됬다가 duration의 중간쯤에 빨라지고, 완료되기 전에 다시 천천히 진행되는 옵션

 

  • static var curveEaseIn: UIView.AnimationOptions

    • 천천히 진행됬다가 진행되면서 조금씩 속도가 높아진다.

 

  • static var curveEaseOut: UIView.AnimationOptions

    • 빠르게 진행됬다가 완료됬을때 천천히 진행

 

 

 

여기까지 UIView.animate의 사용법과 Spring 애니메이션, 옵션들에 대해 알아보았습니다.

다음 포스트엔 순차적으로 진행되는 애니메이션인 Keyframe Animation에 대해 알아보도록 하겠습니다. :]