Skip to content
tezvyn:

MatchedGeometryEffect: Shared Element Hero Transitions

MediumHow cards are made

MatchedGeometryEffect lets two views share one spatial identity, so a thumbnail can appear to fly into a detail sheet across view hierarchies. It only works if both views exist simultaneously during a withAnimation block; otherwise the transition snaps.

Why it exists

Before matched geometry effects existed, building a hero animation in SwiftUI required manually reading global frames with GeometryReader, converting between coordinate spaces, and driving animation values yourself. This was fragile because view hierarchies often changed during transitions, causing frame reads to return incorrect or zero rectangles. MatchedGeometryEffect was introduced to automate the spatial bridging between two views so the framework could handle the interpolation reliably.

The mental model

Think of it as giving two separate views the same seat in the room. Even though they live in different parts of the view hierarchy and may never exist on screen at the same time for long, SwiftUI treats them as the same object moving through space. One view donates its current frame as the starting rectangle, and the other view receives that rectangle as its target. The system then animates a proxy representation between those two rectangles while the actual views swap in and out.

How it works

You create a Namespace.ID, typically stored as a state property using Namespace. You attach the matchedGeometryEffect modifier to two views, giving each the same string identifier and the same namespace instance. One view acts as the source and the other as the destination. When a state change triggers a transition, SwiftUI captures the global bounds of both views and interpolates the position and size during the animation window. The modifier only affects frame geometry; it does not automatically animate opacity, corner radius, or other visual properties unless you add those animations separately.

When to use it

Use this modifier when you want a shared element transition, such as a thumbnail flying into a detail image, a list row expanding into a card, or a sidebar icon morphing into a toolbar button. It shines whenever the same conceptual content appears in two visually distinct places and you want to reinforce the relationship with a spatial animation rather than a simple fade.

When not to use it

Do not use it for views that already live in the same container and can be repositioned with a simple frame or offset change. Avoid it when you need to animate non-geometric properties like color or shadow radius, because the modifier ignores them. It is also a poor fit for drag-driven interactive transitions where the user's finger position must drive the animation progress in real time, since matched geometry is designed for state-driven transitions rather than gesture-driven scrubbing.

One canonical example

Imagine a photo grid where tapping a thumbnail opens a full-screen detail view. Both the grid cell and the detail image carry matchedGeometryEffect with identical identifiers and a shared namespace. Wrapped inside a withAnimation block, the state change that swaps the grid for the detail triggers SwiftUI to project an animated proxy that appears to carry the photo from its small grid position to the large centered frame, creating a smooth hero transition without manual frame calculations.

Interview question

During a matchedGeometryEffect transition, what does SwiftUI primarily interpolate between the source and destination views?

  • a.The offset and scale of two views embedded in the same VStack or ZStack.
  • b.The progress of a drag gesture to scrub the animation interactively.
  • c.The opacity, corner radius, and other visual properties alongside the frame.
  • d.The global frame bounds between two views sharing the same namespace and identifier.Correct
Why?

MatchedGeometryEffect captures the global bounds of both views and interpolates position and size, but it ignores visual properties like opacity or corner radius. It is designed for bridging separate view hierarchies, not for simple container repositioning or gesture-driven scrubbing.

Just read this? Test yourself on what you have been reading.

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on swiftui — each one lists the topics its interview covers.

See open roles