Design Converter
Education
Last updated on Jan 20, 2025
Last updated on Jan 20, 2025
Creating seamless animations between views in SwiftUI is now easier than ever with the MatchedGeometryEffect. It allows developers to create smooth transitions by animating shared geometry across different views.
In this blog, we will explore how to use MatchedGeometryEffect effectively, focusing on geometry, layout, and other key properties to achieve a fluid UI experience.
The MatchedGeometryEffect is a SwiftUI modifier that lets you animate between two views by sharing the same identifier within the same namespace. By defining initial and final states, this feature ensures smooth transitions for geometry like position, frame, and even background. It's commonly used in hero animations, where one view transforms into another, often accompanied by frame width and background changes.
Before diving into examples, let's discuss the structure of this modifier. Here's a step-by-step approach to using it:
Define a Namespace: Use @Namespace
to create a namespace shared between two views.
Assign Identifiers: Use a unique matchedgeometryeffect id for each pair of views.
Trigger Animations: Use a toggle or a similar trigger to switch between the initial and final states.
Let's start with a basic hero animation example where a rectangle transitions between two views.
1import SwiftUI 2 3struct ContentView: View { 4 @Namespace private var animationNamespace 5 @State private var isExpanded = false 6 7 var body: some View { 8 VStack { 9 if isExpanded { 10 Rectangle() 11 .fill(Color.blue) 12 .frame(width: 300, height: 300) 13 .matchedGeometryEffect(id: "rectangle", in: animationNamespace) 14 .onTapGesture { isExpanded.toggle() } 15 } else { 16 Circle() 17 .fill(Color.blue) 18 .frame(width: 100, height: 100) 19 .matchedGeometryEffect(id: "rectangle", in: animationNamespace) 20 .onTapGesture { isExpanded.toggle() } 21 } 22 } 23 } 24}
• The@Namespace
creates the same namespace for two views.
• The matchedgeometryeffect id ("rectangle")
ensures the geometry is shared.
• The toggle on tap switches the frame, shape, and other properties between the initial and final states.
The MatchedGeometryEffect modifier allows for significant customization:
• frame maxwidth infinity: Combine with .frame(maxWidth: .infinity)
for flexible layouts.
• alignment and position: Adjust the placement of elements.
• background and fill: Animate color changes smoothly.
• spring animation: Add a natural response with .animation(.spring()).
1struct AnotherExampleView: View { 2 @Namespace private var animationNamespace 3 @State private var isExpanded = false 4 5 var body: some View { 6 VStack { 7 if isExpanded { 8 RoundedRectangle(cornerRadius: 25) 9 .fill(Color.blue) 10 .frame(height: 200) 11 .padding() 12 .matchedGeometryEffect(id: "rounded", in: animationNamespace) 13 } else { 14 Spacer() 15 RoundedRectangle(cornerRadius: 25) 16 .fill(Color.blue) 17 .frame(width: 100, height: 100) 18 .matchedGeometryEffect(id: "rounded", in: animationNamespace) 19 Spacer() 20 } 21 } 22 .onTapGesture { 23 withAnimation { 24 isExpanded.toggle() 25 } 26 } 27 } 28}
To create complex animations, you can combine MatchedGeometryEffect with:
• overlay: Add additional elements during the transition.
• offset: Move the view during animations.
1struct OverlayExampleView: View { 2 @Namespace private var animationNamespace 3 @State private var showDetail = false 4 5 var body: some View { 6 ZStack { 7 if showDetail { 8 Rectangle() 9 .fill(Color.blue) 10 .frame(maxWidth: .infinity, maxHeight: .infinity) 11 .overlay(Text("Details").font(.largeTitle).foregroundColor(.white)) 12 .matchedGeometryEffect(id: "box", in: animationNamespace) 13 } else { 14 Circle() 15 .fill(Color.blue) 16 .frame(width: 100, height: 100) 17 .overlay(Text("Tap Me").foregroundColor(.white)) 18 .matchedGeometryEffect(id: "box", in: animationNamespace) 19 .onTapGesture { withAnimation { showDetail.toggle() } } 20 } 21 } 22 } 23}
Use Consistent Identifiers: Ensure the same identifier is used for two views.
Simplify Initial and Final States: Focus on animating a few properties like frame, background, or position.
Group Views: Wrap related views in a Group to manage complexity.
Avoid Unnecessary Modifiers: Stick to the matchedgeometryeffect modifier for smooth results.
The MatchedGeometryEffect brings life to UI by creating smooth transitions between views. By using the same namespace and identifier, you can easily animate initial and final states with minimal effort. With these techniques, you'll master the art of fluid geometry animations in SwiftUI.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.