궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFTUI/Grammar

SwiftUI : @Namespace / matchedGeometryEffect() 애니메이션 동기화

서근
QUOTE THE DAY

“ 새로운 프로그래밍 언어를 배우는 유일한 방법은 그 언어로 프로그램을 만드는 것이다. ”

- Dennis Ritchie (데니스 리치)
Written by SeogunSEOGUN

SwiftUI : @Namespace / matchedGeometryEffect() 애니메이션 동기화

.matchedGeometryEffect 에 대해 알아보도록 합시다.

MatchedGeometryEffect

만약 view계층의 서로 다른 부분에 동일한 view가 나타나는 등 두 view사이에 애니메이션 효과를 주려면 .matchedGeometryEffec()수정자를 사용하는 것이 좋습니다.

 

이 수정자를 사용하려면 동일한 view모두에 이 수정자를 연결해줘야 합니다. 이렇게 하면 두 개의 view상태를 전환 할 때 SwiftUI가 동기화된 view에 원활하게 애니메이션을 적용시킬 수 있습니다.

 

우선 간단하게 가장 쉬운 animation효과만 적용시켜서 예를 들어보겠습니다. 

swift
UNFOLDED
import SwiftUI
struct ContentView: View {
@State private var isFlipped = false
var body: some View {
HStack {
if isFlipped {
Text("서근 개발노트")
.font(.subheadline)
Image(systemName: "arrow.right")
.font(.title2)
} else {
Image(systemName: "arrow.left")
.font(.title2)
Text("서근 개발노트")
.font(.subheadline)
}
}
.onTapGesture {
withAnimation {
isFlipped.toggle()
}
}
}
}

위 코드를 프리뷰에서 실행해면 뷰를 그냥 페이드인 / 아웃하여 전환하는 것을 확인할 수 있습니다. 

SwiftUI : @Namespace / matchedGeometryEffect() 애니메이션 동기화 - MatchedGeometryEffect

하지만 뭔가 부자연 스럽고 뒤에 텍스트가 겹쳐서 보기 싫죠? 이것을 해결해 주는 것이 바로 .matchedGeometryEffec()수정자 인거죠 :) 이 수정자는 @Namespace속성 래퍼를 사용하여 뷰에 대한 Name space를 만들어야 합니다. 

 

따라서 다음과 같은 속성을 추가 할 수 있습니다. @Namespace private var animation

 

그리고 원하는 뷰 아래에 .matchedGeometryEffect(id: "사용자의 Indentifier를 적어줌", in: animation)으로 동기화된 효과로 애니메이션을 적용하려는 모든뷰에 적용시켜줘야 합니다.  수정자의 id부분은 고유 번호로 대체되어야 합니다.

 

이렇게 말이죠

swift
UNFOLDED
// 텍스트에 적용
.matchedGeometryEffect(id: "title", in: animation)
// Image에 적용
.matchedGeometryEffect(id: "icon", in: animation)

자 이제 위에 내용을 토대로 아래와 같이 코드를 재 설정 해줄 수 있습니다.

swift
UNFOLDED
import SwiftUI
struct ContentView: View {
@State private var isFlipped = false
@Namespace private var animation
var body: some View {
HStack {
if isFlipped {
Text("서근 개발노트")
.font(.subheadline)
.matchedGeometryEffect(id: "title", in: animation)
Image(systemName: "arrow.right")
.font(.title2)
.matchedGeometryEffect(id: "icon", in: animation)
} else {
Image(systemName: "arrow.left")
.font(.title2)
.matchedGeometryEffect(id: "icon", in: animation)
Text("서근 개발노트")
.font(.subheadline)
.matchedGeometryEffect(id: "title", in: animation)
}
}
.onTapGesture {
withAnimation {
isFlipped.toggle()
}
}
}
}

이제 두 코드를 아래 결과로 비교해보도록 하겠습니다.

 

.matchedGeometryEffect 미적용

SwiftUI : @Namespace / matchedGeometryEffect() 애니메이션 동기화 - MatchedGeometryEffect

.matchedGeometryEffect 적용

SwiftUI : @Namespace / matchedGeometryEffect() 애니메이션 동기화 - MatchedGeometryEffect

응용 방법

음악 앱에서 하단에 있는 앨범을 터치하면 작은 모양인 앨범이 화면에 꽉 차도록 확장되죠? 그런 식으로 애니메이션 효과를 적용할 수 있습니다. 

swift
UNFOLDED
import SwiftUI
struct ContentView: View {
@State private var isZoomed = false
@Namespace private var animation
var frame: CGFloat {
isZoomed ? .infinity : 60
}
var body: some View {
VStack {
Spacer()
VStack {
HStack {
Image("Rollin")
.resizable()
.scaledToFill()
//isZoomed이 true이면 프레임 infinity fales이면 60
.frame(width: frame, height: frame)
//isZoomed이 true이면 padding 10 아니면 0
.padding([.top,.bottom], isZoomed ? 10 : 0)
if isZoomed == false {
Text("브레이브 걸스 - Rollin'")
.matchedGeometryEffect(id: "title", in: animation)
.font(.headline)
Spacer()
}
}
if isZoomed != false {
Text("브레이브 걸스 - Rollin'")
.matchedGeometryEffect(id: "title", in: animation)
.font(.headline)
.padding([.vertical, .horizontal], 10)
Spacer()
}
}
.onTapGesture {
withAnimation(.spring()) {
isZoomed.toggle()
}
}
.frame(maxWidth: .infinity)
.frame(height: .infinity)
.background(Color(white: 0.98))
.foregroundColor(.primary)
}
}
}

SwiftUI : @Namespace / matchedGeometryEffect() 애니메이션 동기화 - MatchedGeometryEffect - 응용 방법

 

 

읽어주셔서 감사합니다🤟

 

본 게시글의 전체코드 GitHub 👇🏻

 

Seogun95/SwiftUI_matchedGeometryEffect

SwiftUI matchedGeometryEffect. Contribute to Seogun95/SwiftUI_matchedGeometryEffect development by creating an account on GitHub....

github.com

 

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.

'SWIFTUI > Grammar' 카테고리의 다른 글

SwiftUI : onAppear()  (0) 2021.05.14
SwiftUI : Identifiable protocol  (1) 2021.05.03
SwiftUI를 위한 Clean 아키텍처  (1) 2021.04.06
SwiftUI : @Environment 프로퍼티 래퍼  (0) 2021.04.06
SwiftUI : EnvironmentValues  (0) 2021.04.05


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.