Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- MVVM
- rxswift
- 애니메이션
- swift documentation
- uitableview
- ios
- UICollectionView
- UITextView
- ribs
- 클린 코드
- tableView
- Observable
- Human interface guide
- Protocol
- swiftUI
- HIG
- SWIFT
- RxCocoa
- Xcode
- 리펙토링
- collectionview
- uiscrollview
- 리팩토링
- clean architecture
- Clean Code
- Refactoring
- 스위프트
- 리펙터링
- combine
- map
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] 부모 뷰와 자식 뷰 사이의 애니메이션 동작 원리, geometryGroup(), transformEffect(.identity) 본문
iOS 응용 (SwiftUI)
[iOS - SwiftUI] 부모 뷰와 자식 뷰 사이의 애니메이션 동작 원리, geometryGroup(), transformEffect(.identity)
jake-kim 2025. 3. 19. 01:01부모 뷰와 자식 뷰 사이의 애니메이션 처리 원리
- 토글 버튼이 있고 이걸 누를때마다 Text의 문자가fade효과를 내면서 새로 등장하는 애니메이션을 준다고 한 경우 아래처럼 작성이 가능
struct ContentView: View {
@State var toggle = false
var body: some View {
VStack {
Button("updown Toggle") {
toggle.toggle()
}
Text(toggle ? "is toggled" : "not toggled")
.animation(.smooth(duration: 1), value: toggle)
}
}
}
- 여기서 toggle 여부에 따라 height 조절해주고 싶은 요구사항이 생긴 경우?
struct ContentView: View {
@State var toggle = false
var sizeHeight: CGFloat {
toggle ? 200 : 300
}
var body: some View {
VStack {
Button("updown Toggle") {
toggle.toggle()
}
Text(toggle ? "is toggled" : "not toggled")
.frame(height: sizeHeight) // <-
.animation(.smooth(duration: 1), value: toggle)
}
}
}
결과) Text를 보면 제자리에서 사라지는 효과가 나와야하는데, 위치가 바뀐 후 사라지는 현상 발생
- 기대 동작은 아래처럼 Text가 제자리에서 사라지는것이 목적
- 이런 현상은 뷰 업데이트 순서를 이해하면 알 수 있음
뷰의 업데이트 순서
- height가 300 -> 200으로 변하는 순간 Text의 위치가 내려간 후 다시 올라오는 지점을 확인
var body: some View {
VStack {
Button("updown Toggle") {
toggle.toggle()
}
Text(toggle ? "is toggled" : "not toggled")
.frame(height: sizeHeight)
.background(Color.gray.opacity(0.1)) // <- 가시성을 위해 추가
.animation(.smooth(duration: 1), value: toggle)
}
}
- Text의 위치가 내려가는 이유?
- 버튼을 누르는 순간 '바뀐 정보인 height 300 -> 200' 정보를 자식뷰가 수신하기전에 애니메이션이 업데이트됨
- 자식뷰는 크기 300을 기준으로 보고 자기 자신을 업데이트 하는데 이미 부모 뷰의 크기는 200으로 반영되어 작아진 상태
- 부모뷰는 200이라는 수치를 가지고 업데이트 -> 자식뷰는 300이라는 수치를 가지고 업데이트
- 부모뷰가 작아진 상태에서 자식뷰를 업데이트 하려고하니 이런 현상 발생
- 결국 애니메이션 특성 상 이전 상태를 유지하려는 특성 때문
해결 방법 - animationGroup() or transformEffect(.identity)
- 자식뷰 입장에서 부모 뷰의 변경사항 정보를 먼저 수신하고난 후 업데이트하면 해결됨
- 이 방법은 animationGroup()을 추가하거나 transformEffect(.identity)를 사용하는 것
- 둘 다 자식뷰 입장에서 부모 뷰의 변경사항을 기다린다는 의미로 사용
// geometryGroup()
Text(toggle ? "is toggled" : "not toggled")
.geometryGroup() // <-
.frame(height: sizeHeight)
.background(Color.gray.opacity(0.1))
.animation(.smooth(duration: 1), value: toggle)
// .transformEffect(.identity)
Text(toggle ? "is toggled" : "not toggled")
..transformEffect(.identity) // <-
.frame(height: sizeHeight)
.background(Color.gray.opacity(0.1))
.animation(.smooth(duration: 1), value: toggle)
결과)
*전체 코드)
import SwiftUI
struct ContentView: View {
@State var toggle = false
var sizeHeight: CGFloat {
toggle ? 200 : 300
}
var body: some View {
VStack {
Button("updown Toggle") {
toggle.toggle()
}
Text(toggle ? "is toggled" : "not toggled")
.transformEffect(.identity) // <-
.frame(height: sizeHeight)
.background(Color.gray.opacity(0.1))
.animation(.smooth(duration: 1), value: toggle)
}
}
}
#Preview {
ContentView()
}
* 참고
- https://developer.apple.com/documentation/swiftui/view/geometrygroup()
'iOS 응용 (SwiftUI)' 카테고리의 다른 글
[iOS - SwiftUI] 뷰 주입받는 방법 (Generics, AnyView) (0) | 2025.03.12 |
---|---|
[iOS - SwiftUI] Spacer(minLength:)를 사용할때 주의할 점 (0) | 2025.03.05 |
[iOS - SwiftUI] 그라데이션 넣는 방법 (Linear Gradation) (0) | 2025.02.26 |
[iOS - SwiftUI] 뷰에서 if, else 구분해야할때 id 활용하는 방법 (SwiftUI의 id) (0) | 2025.02.19 |
[iOS - SwiftUI] 키보드 높이 구하는 방법 (#combine) (0) | 2025.02.12 |
Comments