How to use MatchedGeometryEffect in SwiftUI | Advanced Learning #4
Shape
)을 매칭시키는 효과id
, namespace
가 동일한 서로 다른 두 도형을 같다고 인식하게 만듦offset
을 주지 않고 이동 효과를 주기Circle().matchedGeometryEffect(id: "rectangle", in: namespace)
...
RoundedRectangle(cornerRadius: 25).matchedGeometryEffect(id: "rectangle", in: namespace)
...
if selected == category {
RoundedRectangle(cornerRadius: 10)
.fill(Color.red.opacity(0.5))
.matchedGeometryEffect(id: "category_background", in: namespace2)
.frame(width: 35, height: 2)
.offset(y: 10)
}
import SwiftUI
struct MatchedGeometryEffect: View {
@State private var isClicked: Bool = false
@Namespace private var namespace
var body: some View {
VStack {
if !isClicked {
Circle()
.matchedGeometryEffect(id: "rectangle", in: namespace)
.frame(width: 100, height: 100)
}
Spacer()
if isClicked {
RoundedRectangle(cornerRadius: 25)
.matchedGeometryEffect(id: "rectangle", in: namespace)
.frame(width: 300, height: 200)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.red)
.onTapGesture {
withAnimation(.easeInOut) {
isClicked.toggle()
}
}
}
}
Circle
과 RoundedRectangle
이 서로 다른 위치에 구현되어 있고 isClicked
라는 @State
불리언 변수를 통해 어떤 이미지를 뷰에 보여줄지 결정한다.matchedGeometryEffect
모디파이어를 통해 '같은' 네임 스페이스를 가지고 있기 때문에 서로 같은 shape
로 컴파일러가 인식, 이동 가능struct MatchedGeometryEffectExample2: View {
let categories: [String] = ["Home", "Popular", "Saved"]
@State private var selected: String = ""
@Namespace private var namespace2
var body: some View {
HStack {
ForEach(categories, id: \.self) { category in
ZStack(alignment: .bottom) {
if selected == category {
RoundedRectangle(cornerRadius: 10)
.fill(Color.red.opacity(0.5))
.matchedGeometryEffect(id: "category_background", in: namespace2)
.frame(width: 35, height: 2)
.offset(y: 10)
}
Text(category)
.foregroundColor(selected == category ? .red : .black)
}
.frame(maxWidth: .infinity)
.frame(height: 55)
.onTapGesture {
withAnimation(.spring()) {
selected = category
}
}
}
}
.padding()
}
}
selected
를 통해 어떤 텍스트를 골랐는지 고른 뒤 matchedGeometryEffect
를 통해 어떤 텍스트 밑의 보더 라인을 보여줄지 결정 가능