일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- dataflow
- ios
- 데이터최적화
- CS
- RxSwift
- ar
- stateobject
- GCD
- Concurrency
- fullscreencover
- auth
- 네트워크
- authentication
- firebase
- Animation
- SwiftUI
- WWDC
- UIKit
- withAnimation
- combine
- 달력
- swift
- iphone
- arkit
- gesture
- realitykit
- environmentobjet
- state
- Network
- Performance
- Today
- Total
XLOG
[SwiftUI] Animation 적용 기본 이론편 본문
기본적으로 SwiftUI 에 애니메이션을 적용하기 위해 .animation(_:value:) 를 사용하거나 withAnimation() 을 사용했다.
1. 둘의 차이
우선 이 둘의 차이에 대해 먼저 확인을 해보자. animation(_:value:) 는?
먼저 .animation() 이다. 인스턴스 메소드로 some View 를 리턴한다. view를 리턴한다는 것은 viewModifier 로 생각하면 되는 것 같다. 변화를 추적할 값 V 의 변화를 감지, 그로 인해 영향을 받는 변수들을 animation 옵션에 따라 state 의 변화를 주어 해당 View에 애니메이션을 적용한다.
그렇다면 withAnimation은 ?
withAnimation은 함수이다. 결과값을 Return 한다. 즉 결과값을 리턴을 하게 되면 withAnimation은 메모리에서 해제가 될 수 있다고 생각된다. withAnimation 의 경우 클로져 내부에 변화를 주는 변수와 관련이 있는 모드 State의 변화를 준다. 즉 modifier처럼 하나의 view에 적용하는 것이 아닌 그 변수를 포함하고 있는 모든 View에 변화를 주게 된다.
일단 이렇게 말로만 하면 이해가 어려우니, 예시코드와 실제 동작에 대해 살펴보자.
2. 예시 코드 및 동작 예시
먼저 animation() 을 살펴보자.
struct AnimationView: View {
@State var animationToggle: Bool = true
var body: some View {
VStack {
HStack {
VStack {
Text("\(animationToggle ? "Red" : "Blue")")
.animation(.easeInOut(duration: 2), value: animationToggle)
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(animationToggle ? 0 : 10)
.foregroundColor(animationToggle ? .red : .blue)
.animation(.easeInOut(duration: 2), value: animationToggle)
.onTapGesture {
animationToggle.toggle()
}
}
VStack {
Text("\(animationToggle ? "Red" : "Blue")")
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(animationToggle ? 0 : 10)
.foregroundColor(animationToggle ? .red : .blue)
.onTapGesture {
animationToggle.toggle()
}
}
}
}
}
}
HStack 으로 왼쪽과 오른쪽 animationToggle 값에 의해 상태값의 변화를 주도록 했고, 왼쪽만 animation ViewModifier를 적용했다. 이 경우 왼쪽, 오른쪽 어느쪽을 탭을 하든지 왼쪽만 animation viewModifier를 거쳐서 View에 애니메이션이 적용된다.
그렇다면 withAnimation 은 어떨까?
VStack {
HStack {
VStack {
Text("\(animationToggle ? "Red" : "Blue")")
.animation(.easeInOut(duration: 2), value: animationToggle)
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(animationToggle ? 0 : 10)
.foregroundColor(animationToggle ? .red : .blue)
.animation(.easeInOut(duration: 2), value: animationToggle)
.onTapGesture {
withAnimation(.easeInOut(duration: 2)) {
animationToggle.toggle()
}
}
}
VStack {
Text("\(animationToggle ? "Red" : "Blue")")
Rectangle()
.frame(width: 100, height: 100)
.cornerRadius(animationToggle ? 0 : 10)
.foregroundColor(animationToggle ? .red : .blue)
.onTapGesture {
withAnimation(.easeInOut(duration: 2)) {
animationToggle.toggle()
}
}
}
}
}
위의 코드에서 onTapGesture 클로져 내부에 withAnimation만 적용시켰다. 이 경우 animation modifier가 있든 없든 view의 state 값들을 일정한 애니메이션을 적용하여 값을 변화시킨다. 즉 좌우 어느곳을 탭하더라도 동일한 애니메이션 효과를 얻을 수 있다.
3. 동작원리
두 개의 동작원리는 똑같다고 볼 수 있다. 우리는 SwiftUI 가 State 값에 의해 View 를 re rendering 한다는 것을 알고 있다. 여기에서 buttonToggle 값으 animation의 Trigger 라고 생각해도 된다. buttonToggle의 값의 변화로 view 에서는 animation을 생성한다. 여기서 animation 은 state 값의 변화다. 그 변화를 주는 방법은 다양한다. linear, eassIn, easeOut, easeInOut, smooth, snappy, bouncy....
간단하게 linear 는 일정한 가속도로 state값의 변화를 주게 된다. animation은 frame 단위로 state 값의 변화를 주고 view를 re Rendering 하는 것이다.
즉 위에 easeInOut 이 아니라 linear 로 duration을 2초로 설정했다면, button이 토글되는동안 60hz 의 아이폰은 한 프레임다 cornerRadius 값을 10 / 120 씩 증가시키는 것이다.
4. animation VS withAnimation 어떤것을 사용해야 하는가?
사실 여기에 정답은 없어보인다. 개인적으로는 withAnimation 이 메모리 관리 측면에서, 사용후 메모리가 해제되는 modifier 형태의 animation 보다 효율이 좋지 않을까 생각된다. 하지만 그 비중이 크지 않을 것 같다.
그럼에도 withAnimation이 더 좋게 느껴지는 것은 swiftUI 의 경우 변수를 쉽게 binding 할 수 있다. 즉 여러 구조체에 변수를 binding 을 한다면 서로 다른 View 구조체에 일정한 Trigger로 애니메이션 효과를 줄 수 있으며 .animation modifier를 사용하지 않아도 되기 때문에 중복 코드를 줄일 수 있지 않을까 싶다.
'Swift > SwiftUI' 카테고리의 다른 글
[SwiftUI] Infinity Carousel 구현 (0) | 2023.12.01 |
---|---|
[SwiftUI] Camera Shutter Button Animation (0) | 2023.09.18 |
[SwiftUI] QR Code Scanner 만들기 (SwifUI 에 ViewController 사용하기) (1) | 2023.03.08 |
[SwiftUI] 날짜 계산, 월간달력 만들기 (0) | 2023.03.04 |
[SwiftUI] 캘린더용 InfinityScroll 로직에 대한 아이디어 (0) | 2023.02.27 |