Keyframe Animation
이번 포스트는 애니메이션의 연속적인 처리에 유용한 keyframe에 대해 알아 보도록 하겠습니다.
지난 포스트는 UIView.animate를 이용해서 애니메이션을 구현하는 방법에 대해 알아보았습니다.
간단한 애니메이션같은 경우에는 충분히 커버가 가능하지만, 순차적으로 애니메이션들이 진행된다고했을때,
아래와 같이 completion 클로저를 이용해서 애니메이션을 구현해야됩니다.(콜백지옥...)
UIView.animate(withDuration: 1, animations: {
animate1()
}, completion: { finished in
UIView.animate(withDuration: 1, animations: {
animate2()
}, completion: { finished in
UIView.animate(withDuration: 1, animations: {
animate3()
})
})
})
하지만!
이 방법은 애니메이션의 수가 늘어날 수록 중첩수가 늘어나기 때문에 효율적이지 못합니다.
이러한 순차적인 애니메이션을 구현한다고 했을때, UIView.animate보다 keyframe 사용하면 보다 더 효율적이고 가독성이 좋습니다.
구현 방법
- animateKeyframes
class func animateKeyframes(
withDuration duration: TimeInterval,
delay: TimeInterval,
options: UIView.KeyframeAnimationOptions = [],
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil
)
- addKeyframe
class func addKeyframe(
withRelativeStartTime frameStartTime: Double,
relativeDuration frameDuration: Double,
animations: @escaping () -> Void
)
UIView.animateKeyframes안에 addKeyframe을 추가하는 방식으로 시간의 순서대로 애니메이션을 동작시킬 수 있습니다.
사용 방법
UIView.animateKeyframes(withDuration: 4.0, delay: 0, options: [],
animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.25) { self.animate1() }
UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25) { self.animate2() }
UIView.addKeyframe(withRelativeStartTime: 0.50, relativeDuration: 0.25) { self.animate3() }
UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25) { self.animate4() }
}, completion: nil)
withDuration
4.0 값이 4.0이면 전체 애니메이션 시간은 4초간 진행된다는건 이제 잘 알실겁니다.
delay, options 또한 UIView.animate와 동일합니다!
UIView.addKeyframe의 withRelativeStartTime과 relativeDuration은 무엇일까요?
0.0 ~ 1.0까지의 값을 사용할 수 있으며, 이름 자체에서 느껴졌듯이 기간(withDuration)과 상대적인 시간입니다.
즉, 전체 애니메이션 시간 4초를 1로 보고 4가지의 애니메이션을 순차적으로 진행한다고 했을때
0.25초씩(= 1 / 애니메이션 갯수) 각각의 애니메이션으로 계산 하면 됩니다!
요놈이 제일 핵심 포인트인듯!
예제를 통해 이해해보도록 하겠습니다!
import UIKit
class KeyframeViewController: UIViewController {
@IBOutlet weak var objectView: UIView!
func animate1() {
let targetFrame = CGRect(x: view.center.x - 50, y: view.center.y - 50, width: 200, height: 200)
objectView.frame = targetFrame
}
func animate2() {
objectView.alpha = 0.0
}
func animate3() {
let targetFrame = CGRect(x: 250, y: 200, width: 50, height: 50)
objectView.frame = targetFrame
objectView.alpha = 1.0
}
@IBAction func animate(_ sender: Any) {
UIView.animateKeyframes(withDuration: 5.0, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.3) {
self.animate1()
}
UIView.addKeyframe(withRelativeStartTime: 0.3, relativeDuration: 0.3) {
self.animate2()
}
UIView.addKeyframe(withRelativeStartTime: 0.6, relativeDuration: 0.4) {
self.animate3()
}
}, completion: nil)
}
}
'iOS' 카테고리의 다른 글
[iOS] Animation 방법(UIViewPropertyAnimator) (0) | 2019.12.23 |
---|---|
[iOS] Autolayout으로 제약조건을 걸었을때 Animation 방법 (0) | 2019.12.23 |
[iOS] Animation 방법(UIView.animate) (2) | 2019.12.23 |
[iOS] 개발자 계정 및 인증서 가이드 (0) | 2019.10.31 |
[iOS] iOS13 Modal Style 및 Life Cycle (0) | 2019.10.30 |