Issue #33
πΆ How matchedGeometryEffect() came to the rescue π¦ΈββοΈ
Play with native iOS components using UI Playground.
Explore and customise native UI components to unlock endless possibilities for your app. Take it to the next level by exporting native SwiftUI code, streamlining development.
Welcome to issue #33 of the iOS Coffee Break Newsletter π¬.
At a previous sprint at work, I had faced a quite interesting challenge where I had to create an animated transition when selecting items from a grid. The goal was to smoothly move the selected item within the grid.
Initially, I experimented with various withAnimation
options but couldn't achieve the desired effect ... until I tried out using SwiftUI's matchedGeometryEffect() modifier π!
Overview
This week, I chose to highlight the matchedGeometryEffect()
modifier because it is a great tool for creating smooth, custom transitions between views β perfect even if you are not confident with animations!
Using unique identifiers, you can blend the geometry of two views with the same identifier creating an animated transition. Transitions like this can be useful for navigation or changing the state of UI elements for example.
Steps to enable the Matched Geometry Effect:
- Assign a unique identifier to each view involved in the transition.
- Declare a namespace using the
@Namespace
property wrapper to group view identifiers. - Apply the
.matchedGeometryEffect(id:in:properties:anchor:isSource:)
modifier to the views participating in the animation.
Once set up, when the animation is triggered, views with the same identifier within the same namespace will seamlessly transition between their states.
My Coffees App
I have assembled a practical example to demonstrate the advantages of using this view modifier. Let's imagine you have an app that displays a grid of different types of coffee β and you want to choose your favorites from that list - moving the selected ones from the one grid to the other with a smooth animation!
Here is a preview of what I am aiming for:
Here is the code:
struct MyCoffeesView: View {
[...]
@Namespace private var namespace
private let coffeesNamespace = "coffeesNamespace"
var body: some View {
ScrollView {
VStack {
HeaderView(title: "Favorites")
LazyVGrid(columns: columns) {
if favoriteCoffees.isEmpty {
CoffeePlaceholderView()
} else {
ForEach(favoriteCoffees) { coffee in
CoffeeView(coffee: coffee)
.matchedGeometryEffect(
id: "\(coffee.name)_\(coffeesNamespace)", in: namespace
)
.onTapGesture {
withAnimation(.easeIn) {
favoriteCoffees.removeAll { $0.id == coffee.id }
}
}
}
}
}
HeaderView(title: "Suggested")
LazyVGrid(columns: columns) {
if filteredSuggestedCoffees.isEmpty {
CoffeePlaceholderView()
} else {
ForEach(filteredSuggestedCoffees) { coffee in
CoffeeView(coffee: coffee)
.matchedGeometryEffect(
id: "\(coffee.name)_\(coffeesNamespace)", in: namespace
)
.onTapGesture {
withAnimation(.easeIn) {
favoriteCoffees.append(coffee)
}
}
}
}
}
}
.padding(.all)
}
.navigationBarTitle("My Coffees", displayMode: .inline)
}
}
To explore the full implementation of the sample application, visit the repository on GitHub.
CURATED FROM THE COMMUNITY
π³ Let's Build: The tree Program - Part I
SwiftToolkit is launching a new series called Let's Build!
In the first article of the series, you will explore file system traversal while building a directory listing tool. This guide will walk you through using PathKit and the Swift Argument Parser to efficiently navigate and display directory structures.
βοΈ Task Cancellation in Swift Concurrency
In most cases, Swift Concurrency automatically manages task cancellation, but there are situations where manual handling is necessary.
Majid's latest article explores Swift's cooperative cancellation model, explaining how developers can take control of task cancellation and decide when and how to stop execution!
π·π»ββοΈ Presenting and Managing Expandable Sections in SwiftUI
Expanding and collapsing views is essential for improving user experience. This is particularly useful when deciding which information to display in limited space.
SerialCoder's latest article covers how to manage the expanded state programmatically and how to let users expand and collapse sections on demand - all done in SwiftUI!