티스토리 뷰
WWDC 23 > Explore SwiftUI animation 를 보다가
iOS 17에서 animation(_:body:) 등장을 알게 되었다.
기존에 animation(_:value:) 잘썼는데 왜 저 인터페이스가 추가되었을까?
WWDC 에 나오는 내용으로 살펴보자.
(참고로 이 글 을 먼저 읽고 오길 추천!)
[1] 문제
이런 코드를 짰는데,
pet 과 상관없는 다른 곳에서도 이 코드를 재사용하고 싶다고 해보자
그래서 이렇게 generic 하게 바꿔줬다.
그럼 어떤 위험이 있을까?
전자처럼 전체 계층구조를 제어할 수 있는 상황이고 leaf component 라면 원하는대로 애니메이션이 잘 작동한다.
하지만 content가 non-leaf component 라면 (== 하위 계층을 가지고 있는 뷰라면)
예상치못한 애니메이션이 발생할 수 있다. // 이걸 돌발 애니메이션 (accidentanal aniamtion) 라고 부름.
돌발애니메이션이 발생하는 예제가 wwdc 에서 안나왔는데.. 내가 이해한대로 대충 만들어보자면..
이렇게 content 가 leaf component 면 괜찮지만
struct Avatar: View {
@Binding var selected: Bool
var content: some View {
Image(systemName: "cloud")
}
var body: some View {
content
.shadow(color: .blue, radius: selected ? 12 : 8)
.animation(.smooth, value: selected)
.scaleEffect(selected ? 5 : 1)
.animation(.bouncy, value: selected)
.onTapGesture {
selected.toggle()
}
}
}
이런 content 가 넘어오게 되면 rotationEffect 도 같이 animation 되어버리게 된다.
var content: some View {
Image(systemName: "cloud")
.rotationEffect(.degrees(selected ? 90 : 0))
}
content 가 어떻게 넘어올지 모르기때문에 이걸 고려해야한다고 말하고 있는 것!
[2] 기존 해결방식
기존에는 content 를 넘겨주는 쪽에서
애니메이션이 가능한 효과 밑에 명시적으로 none 을 써서 돌발애니메이션을 막을 수 있었다.
var content: some View {
Image(systemName: "cloud")
.rotationEffect(.degrees(selected ? 90 : 0))
.animation(.none)
}
[3] 새로운 해결방식
이제는 구현하는 쪽에서 방어를 할 수 있게 된 것이다!
다음과 같이 animation(_:body:) 을 써서
scope 를 두고 scope 내의 코드만 애니메이션 먹이겠다. 하면 된다.
위의 예제도 다시 작성해서 확인해보자.
rotationEffect 는 애니메이션 안먹는 걸 확인할 수 있다.
struct Avatar: View {
@Binding var selected: Bool
var content: some View {
Image(systemName: "cloud")
.rotationEffect(.degrees(selected ? 90 : 0))
}
var body: some View {
content
.animation(.smooth) {
$0.shadow(color: .blue, radius: selected ? 12 : 8)
}
.animation(.bouncy) {
$0.scaleEffect(selected ? 5 : 1)
}
.onTapGesture {
selected.toggle()
}
}
}
좋군! 😎
참고로 저렇게 generic 한 뷰를 안만들더라도 매우 유용하다.
하나의 animation이 여러 effect 들에 다 적용되기 때문에 애니메이션을 원치 않는 effect 에
animation(none) 또는 animation(nil) 을 덕지덕지 적어줘야했었다면 ..
깔끔하게 제거할 수 있을 것!
'🍏 > SwiftUI + Combine' 카테고리의 다른 글
[Combine] ConnectablePublisher (0) | 2024.08.04 |
---|---|
[SwiftUI] Preferences (0) | 2024.05.23 |
[SwiftUI] Drawing Curved Path with Animation (2) | 2023.10.29 |
[SwiftUI] @Observable 매크로 (2) (0) | 2023.07.31 |
[SwiftUI] @Observable 매크로 (1) (1) | 2023.07.31 |
- Total
- Today
- Yesterday
- Dart Factory
- Flutter Spacer
- Python Type Hint
- cocoapod
- 플러터 싱글톤
- Django Firebase Cloud Messaging
- Flutter getter setter
- 플러터 얼럿
- Flutter 로딩
- 구글 Geocoding API
- Django FCM
- Sketch 누끼
- Flutter Clipboard
- flutter dynamic link
- SerializerMethodField
- Flutter Text Gradient
- flutter build mode
- github actions
- METAL
- drf custom error
- DRF APIException
- Watch App for iOS App vs Watch App
- ribs
- PencilKit
- ipad multitasking
- flutter 앱 출시
- 장고 URL querystring
- 장고 Custom Management Command
- flutter deep link
- Django Heroku Scheduler
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |