Home > SwiftUI Animations
SwiftUI Animations
SwiftUI์ ์ ์ธํ ์ ๋๋ฉ์ด์ ์์คํ ์ ํํํฉ๋๋ค. Spring, Keyframe, Phase ๊ธฐ๋ฐ ์ ๋๋ฉ์ด์ ๋ถํฐ geometry ์ ํ๊น์ง, ๋ชจ๋ iOS ์ฑ์ ๋ชจ์ ๋์์ธ ํต์ฌ์ ๋ค๋ฃน๋๋ค.
๊ฐ์
SwiftUI๋ ์ ์ธํ(Declarative) ์ ๋๋ฉ์ด์ ์์คํ ์ ์ ๊ณตํฉ๋๋ค. ์ํ(State) ๋ณ๊ฒฝ์ ์ ์ธํ๋ฉด ํ๋ ์์ํฌ๊ฐ ์๋์ผ๋ก ์ค๊ฐ ํ๋ ์์ ๋ณด๊ฐํ์ฌ ๋ถ๋๋ฌ์ด ์ ํ์ ๋ง๋ค์ด ์ค๋๋ค. UIKit์ ๋ช ๋ นํ ์ ๋๋ฉ์ด์ ๊ณผ ๋ฌ๋ฆฌ, โ์ด๋ป๊ฒ ์์ง์ผ์งโ๊ฐ ์๋๋ผ โ์ต์ข ์ํ๊ฐ ๋ฌด์์ธ์งโ๋ง ๊ธฐ์ ํ๋ฉด ๋ฉ๋๋ค.
์ธ์ ์ฌ์ฉํ๋์?
- UI ์์์ ์์น, ํฌ๊ธฐ, ํฌ๋ช ๋, ์์ ์ ํ
- ํ๋ฉด ์ ํ ๋ฐ ๋ค๋น๊ฒ์ด์ ์ ๋๋ฉ์ด์
- ์ธํฐ๋ํฐ๋ธ ์ ์ค์ฒ ํผ๋๋ฐฑ
- ๋ณต์กํ ๋ค๋จ๊ณ(multi-step) ๋ชจ์ ์ํ์ค
ํต์ฌ API
Implicit vs Explicit Animation
Implicit Animation์ .animation() modifier๋ก ํน์ ๊ฐ ๋ณ๊ฒฝ์ ์ ๋๋ฉ์ด์
์ ๋ฐ์ธ๋ฉํฉ๋๋ค. Explicit Animation์ withAnimation ๋ธ๋ก ์์์ ์ํ๋ฅผ ๋ณ๊ฒฝํ์ฌ ํด๋น ๋ณ๊ฒฝ์ ์ํฅ๋ฐ๋ ๋ชจ๋ ๋ทฐ๋ฅผ ์ ๋๋ฉ์ด์
ํฉ๋๋ค.
// Implicit: ํน์ ํ๋กํผํฐ์ ์ ๋๋ฉ์ด์
๋ฐ์ธ๋ฉ
Circle()
.scaleEffect(isExpanded ? 1.5 : 1.0)
.animation(.spring(duration: 0.5), value: isExpanded)
// Explicit: ์ํ ๋ณ๊ฒฝ ์์ ์ ์ ๋๋ฉ์ด์
์ ์ฉ
withAnimation(.spring(duration: 0.5, bounce: 0.3)) {
isExpanded.toggle()
}
Spring Animation
iOS 17๋ถํฐ spring(duration:bounce:) ํ๋ผ๋ฏธํฐ๋ก ๋ฌผ๋ฆฌ ๊ธฐ๋ฐ ์คํ๋ง์ ๊ฐํธํ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค. bounce ๊ฐ์ด 0์ด๋ฉด ์๊ณ๊ฐ์ (critically damped), ์์์ด๋ฉด ๋ฐ์ด์ค ํจ๊ณผ๊ฐ ๋ํ๋ฉ๋๋ค.
KeyframeAnimator
iOS 17์์ ๋์
๋ KeyframeAnimator๋ ์ฌ๋ฌ ํ๋กํผํฐ๋ฅผ ๋
๋ฆฝ์ ์ธ ํ์๋ผ์ธ์ผ๋ก ์ ์ดํ๋ ํคํ๋ ์ ์ ๋๋ฉ์ด์
์ ์ง์ํฉ๋๋ค.
KeyframeAnimator(initialValue: AnimValues()) { values in
Circle()
.scaleEffect(values.scale)
.rotationEffect(values.rotation)
} keyframes: { _ in
KeyframeTrack(\.scale) {
SpringKeyframe(1.5, duration: 0.3)
SpringKeyframe(1.0, duration: 0.2)
}
KeyframeTrack(\.rotation) {
LinearKeyframe(.degrees(360), duration: 0.5)
}
}
PhaseAnimator
PhaseAnimator๋ ์ ์๋ Phase ๋ฐฐ์ด์ ์์ฐจ์ ์ผ๋ก ์ํํ๋ฉฐ ์๋ ์ ๋๋ฉ์ด์
์ ์คํํฉ๋๋ค. ๋ก๋ฉ ์ธ๋์ผ์ดํฐ๋ ๋ฐ๋ณต ๋ชจ์
์ ์ ํฉํฉ๋๋ค.
matchedGeometryEffect
์๋ก ๋ค๋ฅธ ๋ทฐ ๊ณ์ธต์ ์๋ ๋ ์์ ์ฌ์ด์ ์์น/ํฌ๊ธฐ ์ ํ์ ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐํฉ๋๋ค. ๋ฆฌ์คํธ์์ ๋ํ ์ผ ํ๋ฉด์ผ๋ก์ Hero Transition ๊ตฌํ์ ํต์ฌ์ ์ธ API์ ๋๋ค.
.visualEffect
iOS 17์ .visualEffect modifier๋ geometry proxy ์ ๋ณด(์์น, ํฌ๊ธฐ)์ ๊ธฐ๋ฐํ ์๊ฐ ํจ๊ณผ๋ฅผ ์ ์ฉํ ์ ์๊ฒ ํด ์ค๋๋ค. ์คํฌ๋กค ์์น์ ๋ฐ๋ฅธ ํจ๋ด๋์ค, ํ์ , ์ค์ผ์ผ ํจ๊ณผ ๋ฑ์ ๊ตฌํํ ๋ ์ ์ฉํฉ๋๋ค.
๋ฐ๋ชจ ๋ชฉ๋ก
์ฑ์์๋ ๋ ๊ฐ์ ์น์ ์ผ๋ก ๊ตฌ๋ถ๋ฉ๋๋ค.
Foundations
๊ฐ ๋ณํ๋ฅผ ๋ณด๊ฐํ๋ ๊ธฐ๋ณธ ์ ๋๋ฉ์ด์ ํจํด.
| # | ๋ฐ๋ชจ | ์ค๋ช |
|---|---|---|
| 1 | Spring Playground | Spring ํ๋ผ๋ฏธํฐ(response, dampingFraction, blendDuration)๋ฅผ ์ค์๊ฐ์ผ๋ก ์กฐ์ ํ๋ฉฐ ์คํ๋ง ๊ณก์ ์ ๋ณํ๋ฅผ ์๊ฐ์ ์ผ๋ก ํ์ธํฉ๋๋ค. Bouncy/Smooth/Snappy ํ๋ฆฌ์ ๋ ๋น๊ตํ ์ ์์ต๋๋ค. |
| 2 | Morphing Shapes | ์ปค์คํ
Shape์ animatableData: Double์ ํ์ฉํ์ฌ circleโstar, squareโtriangle, heartโdiamond ๋ชจํ ์ ํ์ ๊ตฌํํฉ๋๋ค. ์ฌ๋ผ์ด๋๋ก progress๋ฅผ ์ง์ ์กฐ์ํด ๋ณด๊ฐ ์๋ฆฌ๋ฅผ ๊ด์ฐฐํ ์ ์์ต๋๋ค. |
iOS 17 Multi-State APIs
์ฌ๋ฌ ๋จ๊ณ๋ฅผ ์์ฐจ์ ์ผ๋ก ๋ค๋ฃจ๋ iOS 17์ ์ ์ ๋๋ฉ์ด์ API.
| # | ๋ฐ๋ชจ | ์ค๋ช |
|---|---|---|
| 3 | Keyframe Animations | KeyframeAnimator๋ก ์ฌ๋ฌ ํ๋กํผํฐ(scale, rotation, offset)๋ฅผ ๋
๋ฆฝ์ ํ์๋ผ์ธ์ผ๋ก ์กฐํฉํ๋ ๋ณตํฉ ์ ๋๋ฉ์ด์
. bounce, orbit, shake, wave ํ๋ฆฌ์
์ ์ ๊ณตํฉ๋๋ค. |
| 4 | Phase Animations | PhaseAnimator๋ฅผ ํ์ฉํ ์๋ ๋ฐ๋ณต ์ ๋๋ฉ์ด์
. ๋ก๋ฉ ์ธ๋์ผ์ดํฐ, ํ์ฑ ์๋ฆผ ๋ฑ์ง, ์ํ ์ ํ ํ์(connecting โ connected โ synced) ์ธ ๊ฐ์ง ์ฌ์ฉ ์์์
๋๋ค. |
์ค์ ํ
Best Practices
- ๋จ์ผ ํ๋กํผํฐ ๋ณ๊ฒฝ์๋ Implicit(
.animation)์ด ๊ฐ๊ฒฐํ๊ณ ์์ ํฉ๋๋ค. - ์ฌ๋ฌ ์ํ๋ฅผ ๋์์ ๋ณ๊ฒฝํ ๋๋
withAnimation(Explicit)์ ์ฌ์ฉํ์ธ์. - Spring Animation์
bounce: 0์ ์์ฐ์ค๋ฌ์ด ๊ฐ์ ํจ๊ณผ๋ฅผ ์ค๋๋ค. Animation.interactiveSpring์ ์ ์ค์ฒ ์ถ์ ์ ์ต์ ํ๋์ด ์์ต๋๋ค.- KeyframeAnimator๋ ๋จ๋ฐ์ฑ ๋ณตํฉ ๋ชจ์ ์, PhaseAnimator๋ ๋ฐ๋ณต ๋ชจ์ ์ ์ ํฉํฉ๋๋ค.
์ฃผ์ ์ฌํญ
.animation()์valueํ๋ผ๋ฏธํฐ๋ฅผ ์๋ตํ๋ฉด ์๋ํ์ง ์์ ํ๋กํผํฐ๊น์ง ์ ๋๋ฉ์ด์ ๋ ์ ์์ต๋๋ค.- matchedGeometryEffect๋ ๋ ๋ทฐ๊ฐ ๋์์ ์กด์ฌํ๋ฉด ์ ๋ฉ๋๋ค (if/else ๋ถ๊ธฐ ํ์).
- ๋ณต์กํ ๋ทฐ ํธ๋ฆฌ์์ ๊ณผ๋ํ ์ ๋๋ฉ์ด์ ์ ํ๋ ์ ๋๋กญ์ ์ ๋ฐํ ์ ์์ต๋๋ค.
- Instruments์ Animation Hitches ๋๊ตฌ๋ก ์ฑ๋ฅ์ ํ๋กํ์ผ๋งํ์ธ์.
- Simulator๋ณด๋ค ์ค๊ธฐ๊ธฐ์์ ์ฑ๋ฅ์ ๋ฐ๋์ ํ์ธํ์ธ์.