안녕하세요.
이번에는 matchedGeometryEffect에 대해 공부해 볼게요.
# matchedGeometryEffect
matchedGeometryEffect는 SwiftUI의 수식어 중 하나입니다.
Defines a group of views with synchronized geometry using an identifier and namespace that you provide.
Identifier(ID)와 namespace를 사용해서 동기화된 geometry로 뷰 그룹을 정의한다.
잘 모르겠....;;
Discussion을 좀 더 살펴볼게요.
If inserting a view in the same transaction that another view with the same key is removed, the system will interpolate their frame rectangles in window space to make it appear that there is a single view moving from its old position to its new position.
(이것도 완벽하게 이해했는진 모르겠으나... 제 맘대로 의역을 하자면) 동일한 트랜잭션에서 동일한 key를 가진 어떤 View가 제거되고 삽입될 때, 시스템이 이전 위치에서 현재 위치로 이동하는 단일 View가 있는 것처럼 화면에 보이도록 하는 것.
이것도 잘 이해가 안 가긴 하네요.....;;;
일단 제가 직접 써봤을 때의 느낌은, 어떤 View의 위치가 변경될 때 단순히 fade-in & fade-out 이 되는 게 아니라 스르륵 이동하는 느낌이었습니다.
몇 가지 예시를 준비했습니다.
# 예시
## 예시 1
아래처럼 화면을 구성해 봤어요.
화면을 클릭하면 애니메이션이 동작하긴 하는데 fade-in & fade-out 됩니다.
화면이 HStack -> VStack으로 바뀌면서 SwiftUI가 화면을 다시 그렸기 때문입니다.
근데 난 이쁜 애니메이션 처리를 하고 싶다고오오오오오오오!!!!!!
그럴 때 matchedGeometryEffect 수식어를 사용합니다.
우선 @Namespace를 정의해 주고,
matchedGeometryEffect 수식어를 적용시켜 주세요.
이때 id와 namespace는 동일한 transaction을 위한 key가 됩니다.
위 예시를 보면, VStack 안에 있는 Circle과 HStack 안에 있는 Circle은 동일한 "circle"이란 id와 같은 namespace를 가지고 matchedGeometryEffect를 적용했으니, VStack의 Circle과 HStack의 Circle은 동일한 transaction으로 애니메이션이 동작한다는 의미가 됩니다.
이렇게요!!
이때 주의할 점이 있어요.
만약 matchedGeometryEffect를 frame 수식어 보다 나중에 적용한다면 어떻게 될까요??
애니메이션이 좀 이상하죠???
완전한 동일한 설정을 가진 상태에서 matchedGeometryEffect를 적용해야지 애니메이션이 이쁘게 동작하는 것 같으니, 이점 주의해 주세요!!!
## 예시 2
이렇게도 활용할 수 있습니다ㅎㅎ
한 가지 드는 생각이 있을 거예요..
아늬.. 나는 ViewBuilder 말고 다른 파일로 분리하고 싶은데.....?
그럴 땐 아래처럼 namespace를 인자로 넘겨주면 됩니다.
[참고]
인자로 넘긴 namespace의 타입은 @Namespace가 아니라 Namespace.ID입니다.
왜냐하면 @Namespace propertyWrapper의 wrappedValue가 Namespace.ID 이기 때문이죠!!
## 예시 3
이렇게도 쓸 수 있답니다ㅎㅎ
# 참고
- https://youtu.be/e7OuerHs8PU
- https://youtu.be/rQU_tc2UyoM
- https://youtu.be/x8h6hTqo2So
이번 글은 여기서 마무리.
'SwiftUI' 카테고리의 다른 글
mask (0) | 2023.03.03 |
---|---|
SwiftUI에서 WKWebView <-> JavaScript 상호작용 (0) | 2023.02.27 |
contentShape (1) | 2023.01.03 |
ScenePhase (5) | 2022.12.26 |
@FocusState (0) | 2022.12.11 |