일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- completion handler
- launch screen
- 네이티브
- ios
- panorama view
- 뷰 정체성
- requirenativecomponent
- @sendable
- 앱 성능 개선
- 리액트 네이티브
- ssot
- SwiftUI
- 360도 뷰어
- react
- 구조적 정체성
- 뷰 생명주기
- 라이브러리 없이
- React Native
- react-native-fast-image
- 360도 이미지
- launchscreen
- 파노라마 뷰
- 스켈레톤 통합
- data driven construct
- 리액트
- Android
- 360도 이미지 뷰어
- React-Native
- native
- 명시적 정체성
- Today
- Total
Neoself의 기술 블로그
SwiftUI | PhaseAnimator, Keyframes으로 고급 애니메이션 구현하기 본문
기본 Animation

withAnimation 수정자나 animation 수정자를 통해 간단한 애니메이션 구현이 가능합니다.
이때 프로그램 상태가 변경되면, SwiftUI는 기존 상태에서 새로운 상태로 보간된 애니메이션을 적용합니다.
Apple의 SwiftUI에서는 고급 애니메이션을 위해 Animation Phases와 Keyframes 기능을 제공하고 있습니다. 이는 두 상태 사이의 애니메이팅만이 아닌 일련의 여러 단계를 정의할 수 있습니다.
Animation Phases
위 기능은 연속된 애니메이션에 적합한 기능으로, phaseAnimator 뷰 수정자를 사용해 구현할 수 있습니다. 해당 뷰 수정자를 통해 각 단계를 정의하는 일련의 상태를 제공하면, SwiftUI는 자동으로 각 상태 사이를 애니메이팅하게 됩니다.
.phaseAnimator([false, true]) { content, phase in
content
.opacity(phase ? 1.0 : 0.5)
} animation: { phase in
.easeInOut(duration: 1.0)
}
위 예제의 경우, true와 false 두개 페이즈를 정의하고 있습니다.
여기서 SwiftUI는 뷰 생성시 false 페이즈로 시작, true 페이즈로 애니메이팅을 진행한 후, 위 과정을 반복하게 됩니다. 필수는 아니지만, animation 클로저를 뒤에 붙일 경우, 애니메이션 유형을 기본 spring 애니메이션에서 변경할 수 있습니다.
여기서 열거형 구조를 같이 활용할 경우, 단계 목록을 설정할 수 있게 됨에 따라 더 복잡한 애니메이션 정의가 가능해집니다.
enum Phase: CaseIterable {
case initial
case move
case scale
var verticalOffset: Double {
switch self {
case .initial: return 0
case .move, .scale: return -64
}
}
var scale: Double {
// 각 단계별 scale 값 정의
}
var foregroundStyle: Color {
// 각 단계별 foregroundStyle 정의
}
}

여기서 주목해야할 점은 phaseAnimator 수정자에 트리거값이 추가되었다는 점인데요. 트리거값이 추가되면서 해당 수정자는 변경값을 관찰하게 됩니다. 이로써 주어진 트리거값이 변경될 경우, 지정된 Phase로 애니메이팅이 시작됩니다.

여기서 animation 클로저 내부에 전달되는 phase는 뷰의 개별 상태를 정의하며, SwiftUI는 상태 사이의 애니메이션을 기존의 animation 뷰 수정자에서 전달받은 phase 인자값을 활용해 각 페이즈마다 다른 애니메이션 유형을 지정한 것도 확인할 수 있습니다.
하지만 phaseAnimator 수정자는 상태 전환이 일어나면서 모든 프로퍼티가 동시에 애니메이팅되어야만 합니다.
즉 각 프로퍼티를 독립적으로 애니메이팅할 수는 없죠. 여기서 Keyframe 기능이 사용됩니다.
Keyframe
위 기능은 animation phase와 달리 사전에 정의된 애니메이션으로 재생 가능한 비디오 클립에 가깝습니다. 이는 타이밍과 움직임을 완전하게 제어할 수 있게 해주므로, 복잡한 애니메이션을 정의하는 데에 유용합니다.


Keyframe은 위 사진과 같이 여러가지 효과를 각기 다른 시점에 배치할 수 있기에 더 강력한 제어를 제공합니다. 하지만 모든 프레임마다 뷰가 업데이트 되기에 리소스 사용량이 높으며, animation phase와 달리 자연스러운 리타겟이 불가능합니다. 즉 유동적, 상호작용형 UI가 필요한 상황에서는 적합하지 않습니다.
Keyframe의 유형은 아래와 같이 정리해볼 수 있습니다.
- LinearKeyframe: 이전 키프레임의 벡터 공간을 선형으로 보간합니다.
- SpringKeyframe: 스프링 효과를 사용하여 자연스러운 움직임을 만듭니다.
- CubicKeyframe: 베지어 곡선을 사용하며, 여러 개를 조합하면 캣멀롬 스플라인과 유사한 부드러운 곡선을 만들 수 있습니다.
- MoveKeyframe: 보간 없이 즉시 값을 변경합니다.



위와 같이 keyframeAnimator 수정자를 추가하여, 후 .scale 프로퍼티에 대해 다양한 키 프레임을 사용해 복잡한 애니메이션을 생성할 수 있으며, 각 키 프레임은 애니메이팅할 프로퍼티를 트랙으로 나누어 프로퍼티별 키 프레임을 분류할 수 있게 해줍니다.

이러한 키 프레임 지정은 모든 속성에 대해 동시에 지정이 가능합니다.
결론
SwiftUI의 Animation Phases와 Keyframes는 복잡하고 세밀한 애니메이션을 구현할 수 있는 강력한 도구입니다. Animation Phases는 연속적이고 반복적인 애니메이션에 적합하며, Keyframes는 더욱 정교한 제어가 필요한 애니메이션에 사용됩니다.
감사합니다.
Reference
https://www.youtube.com/watch?v=NFmQjc7ia4Y
'개발지식 정리 > WWDC 정리' 카테고리의 다른 글
Meet async/await in Swift 정리 (0) | 2025.04.03 |
---|---|
Explore structured concurrency in Swift 정리 (0) | 2025.04.01 |
Understanding Swift Performance 정리 (0) | 2025.01.07 |
SwiftUI 심층정리 (0) | 2024.12.16 |
SwiftUI 애니메이션 정리(Animatable, Animation, Transaction) (0) | 2024.10.15 |