UIViewPropertyAnimator는 애니메이션을 '정의'하고, '시작하고', '일시정지'하거나 '취소'하고, '다시 시작'하는 등의 조작을 할 수 있는 객체이다.
이는 iOS 10부터 도입된 애니메이션 클래스로, 기존의 UIView.animate(...) 방식보다 더 유연하고 정밀한 애니메이션 제어를 가능하게 한다.
startAnimation() 호출 전까지 실행 안 됨)fractionComplete)를 직접 제어 가능UIViewPropertyAnimator는 애니메이션의 실행 상태에 따라 여러가지 상태를 가지게 되고, 그 특징은 아래와 같다.

| 상태 | 설명 | 호출 가능한 Method |
|---|---|---|
| Inactive | 애니메이션 시작 전 | startAnimation(), pauseAnimation() |
| Inactive(finished) | 애니메이션 완료 | - |
| Active | 애니메이션 실행 중 | pauseAnimation(), stopAnimation() |
| Active(paused) | 애니메이션 일시 정지 중 | continueAnimation() |
| Stopped | 애니메이션 중지 됨 | finishAnimation() |
| 메소드 | 설명 |
|---|---|
init(duration: TimeInterval, curve: UIView.AnimationCurve, animations: (() -> Void)?) | 기본적인 cubic curve 기반 애니메이터 생성 |
init(duration: TimeInterval, timingParameters: UITimingCurveProvider) | UISpringTimingParameters 또는 UICubicTimingParameters를 사용해 고급 타이밍 설정 가능 |
| 메소드 | 설명 |
|---|---|
startAnimation() | 애니메이션 시작 |
pauseAnimation() | 애니메이션 일시 정지 |
stopAnimation(_:) | 애니메이션 중단 (true면 현재 위치 고정, false면 완료로 설정됨) |
finishAnimation(at:) | 애니메이션을 특정 위치에서 종료.current, .start, .end |
continueAnimation(withTimingParameters:durationFactor:) | 일시 정지된 애니메이션을 이어서 재생 (다른 타이밍 파라미터로도 가능) |
| 메소드 | 설명 |
|---|---|
addAnimations(_:) | 추가 애니메이션을 기존 애니메이션에 병합 |
addAnimations(_:delayFactor:) | 지연된 애니메이션을 병합 |
addCompletion(_:) | 애니메이션 완료 후 실행할 클로저 등록 (.start, .end, .current 위치 기반) |
| 프로퍼티 | 설명 |
|---|---|
state | 현재 애니메이터 상태 (inactive, active, stopped) |
isRunning | 현재 애니메이션이 실행 중인지 여부 |
fractionComplete | 애니메이션 진행 비율 (0.0 ~ 1.0) — 인터랙티브 컨트롤에 사용 |
scrubsLinearly | true면 fractionComplete가 정확한 비율대로 작동 (보통 true 사용) |
reversed | 애니메이션을 반대로 실행 |
let animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeInOut) {
view.alpha = 0.0
}
animator.startAnimation()
| 파라미터 | 설명 |
|---|---|
| duration | 애니메이션의 지속 시간 |
| curve | 애니메이션 실행 곡선 |
| timingParameters | 고급 타이밍 제어 |
여기서 curve는 애니메이션이 실행되는 형태를 설정하는 파라미터로, .easeInOut, .linear, .easeIn, easeOut 등이 대표적으로 사용된다. 각각의 속성마다 애니메이션이 실행되는 방식이 다르며, 그래프로 표현하자면 아래와 같다.

다음으로 timingParameters가 있는데, 이는 주로 UISpringTimingParameters, UICubicTimingParameters 등을 사용한다. 이들은 애니메이션의 타이밍 곡선을 제어하는데 사용되며, UISpringTimimngParameters는 물리 기반 애니메이션을 제공하고 UICubicTimingParameters는 Bézier 곡선 기반 애니메이션을 제공한다.
특히, iOS의 경우 기본적으로 Spring 기반의 애니메이션을 사용하기 때문에 이를 잘 활용하면 더욱 iOS 스러운 앱을 만들 수 있다.
dampingRatio, frequencyResponse, intialVelocity 등을 조정하여 커스텀 가능// -1 ~ 1 사이의 값. 탄력의 정도를 지정하는 값으로 값이 작을 수록 덜 튕김.
let springParams = UISpringTimingParameters(duration: 1, bounce: 0.5)
// 0 이상. 값이 클수록 출렁임이 줄어들고 1 이상은 출렁이지 않음
let springParams = UISpringTimingParameters(dampingRatio: 0.5)
// mass(질량), stiffness(강성), damping(강쇠), initialVelocity(초기 속도)에 따른 곡선
let springParams = UISpringTimingParameters(mass: 1, stiffness: 50, damping: 5, initialVelocity: .zero)
.easeInOut, .easeIn, .easeOut, .linear 등)controlPoint1, controlPoint2)let cubicParams = UICubicTimingParameters(controlPoint1: CGPoint(x: 0.42, y: 0.0),
controlPoint2: CGPoint(x: 0.58, y: 1.0))
let animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: cubicParams)

let animator = UIViewPropertyAnimator(duration: 1.0, curve: .linear) {
view.frame.origin.x += 100
}
animator.pauseAnimation() // 애니메이션 일시 정지
animator.fractionComplete = 0.5 // 절반 진행된 상태로 설정
animator.continueAnimation(withTimingParameters: nil, durationFactor: 1.0)
var animator: UIViewPropertyAnimator!
func panGestureRecognized(_ recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: view)
let progress = min(max(translation.y / 200, 0), 1)
switch recognizer.state {
case .began:
animator = UIViewPropertyAnimator(duration: 0.5, curve: .easeInOut) {
myView.alpha = 0
myView.transform = .identity
}
animator.pauseAnimation()
case .changed:
animator.fractionComplete = progress
case .ended, .cancelled:
if progress > 0.5 {
animator.continueAnimation(withTimingParameters: nil, durationFactor: 1)
} else {
animator.isReversed = true
animator.continueAnimation(withTimingParameters: nil, durationFactor: 1)
}
default:
break
}
}
| 상황 | 이유 |
|---|---|
| 제스처 기반 인터랙티브 애니메이션 | 진행률을 직접 제어 가능 |
| 복잡한 타이밍 제어 | UISpringTimingParameters 등을 이용하여 자연스러운 움직임 가능 |
| 애니메이션을 나중에 시작 | startAnimation() 호출 전까지 지연 가능 |
| 중간에 애니메이션 조작 필요 | pauseAnimation(), continueAnimation(...) 등으로 유연하게 제어 가능 |
| 항목 | UIView.animate(...) | UIViewPropertyAnimator |
|---|---|---|
| 즉시 시작 | ✅ | ❌ (startAnimation() 필요) |
| 인터랙션 제어 | ❌ | ✅ |
| 진행률 제어 | ❌ | ✅ |
| 중단 및 재시작 | ❌ | ✅ |
| 고급 타이밍 커스터마이징 | 제한적 | 매우 유연 |
오늘은 UIViewPropertyAnimator라는 것을 학습했다.
항상 UIView.animate(...)만 사용했었는데, 이런 클래스가 있는 줄 정말 몰랐다...
기존에 쓰던 UIView.animate(...)와 달리 정교한 제어가 가능하고, 제스처 기반 인터랙션을 구현할 수 있다는 점에서 매력적이라고 생각했다.
간단한 애니메이션은 UIView.animate(...)를 사용해도 되겠지만, UX를 개선하고 보다 나은 앱을 만들기 위해서는 UIViewPropertyAnimator의 사용법을 잘 익히고 잘 사용할 줄 알아야겠다는 생각을 했다.