0Pricing
Swift Academy · Lesson

matchedGeometryEffect for Hero Transitions

Creating seamless hero animations between views with namespace and matched IDs.

matchedGeometryEffect for Hero Transitions is a free Swift Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What is matchedGeometryEffect?

matchedGeometryEffect animates a view's position and size between two states, creating a "hero" transition.

struct HeroDemo: View {
  @Namespace private var ns
  @State private var expanded = false
  var body: some View {
    if expanded {
      BigCard().matchedGeometryEffect(id: "card", in: ns)
    } else {
      SmallCard().matchedGeometryEffect(id: "card", in: ns)
    }
  }
}

Creating a Namespace

Declare a @Namespace in the parent view. All matched views share this namespace.

struct ParentView: View {
  @Namespace private var heroNamespace
}

Applying the Modifier

Apply .matchedGeometryEffect(id:in:) with the same id to both the source and destination views.

Image("cover")
  .matchedGeometryEffect(id: "albumArt", in: heroNamespace)

Triggering the Transition

Wrap the state change in withAnimation to animate the geometry between the two views.

Button("Expand") {
  withAnimation(.spring()) {
    isExpanded.toggle()
  }
}

List to Detail Hero

A classic hero pattern: tap a list item and it expands into a full-screen detail using matchedGeometryEffect.

ForEach(items) { item in
  ThumbnailRow(item: item)
    .matchedGeometryEffect(id: item.id, in: ns)
    .onTapGesture { withAnimation { selected = item } }
}
if let sel = selected {
  DetailView(item: sel)
    .matchedGeometryEffect(id: sel.id, in: ns)
}

isSource Parameter

When two views share an id, mark the origin with isSource: true (default) and the destination with isSource: false.

SmallImage()
  .matchedGeometryEffect(id: "img", in: ns, isSource: true)
LargeImage()
  .matchedGeometryEffect(id: "img", in: ns, isSource: false)

Anchor and Size Properties

Customize which anchor point and which geometry properties (position/size) are matched.

.matchedGeometryEffect(
  id: "box",
  in: ns,
  anchor: .center,
  properties: [.position, .size]
)

Combining with AnyTransition

Combine hero animation with .transition to also control how content fades or slides in.

DetailView()
  .matchedGeometryEffect(id: "card", in: ns)
  .transition(.opacity)

Multiple Heroes in a List

Use unique IDs derived from item identifiers to run multiple independent hero animations.

ForEach(products) { p in
  ProductCard(p)
    .matchedGeometryEffect(id: p.id, in: ns)
}

Common Pitfalls

Both views with the same ID must not appear simultaneously — only one should be visible at any time, or you'll see layout glitches.

// Wrong: both views visible at same time
Small().matchedGeometryEffect(id: "x", in: ns)
Large().matchedGeometryEffect(id: "x", in: ns)
// Correct: use if/else or ZStack with opacity toggling

Performance Tip

Keep matched views lightweight. Complex hierarchies inside matched views can cause dropped frames during the animation.

// Prefer simple shapes inside matched containers
// Move heavy content outside the matched frame

Quick Check

What is required to link two views as source and destination in a hero transition?

Lesson Recap

Create hero transitions with @Namespace and .matchedGeometryEffect(id:in:). Wrap state changes in withAnimation. Ensure only one matched view is visible at a time to avoid layout conflicts.

Frequently asked questions

Is the “matchedGeometryEffect for Hero Transitions” lesson free?

Yes — the full text of “matchedGeometryEffect for Hero Transitions” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.

What will I learn in “matchedGeometryEffect for Hero Transitions”?

Creating seamless hero animations between views with namespace and matched IDs. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Swift Academy?

No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “matchedGeometryEffect for Hero Transitions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Swift Academy lesson?

Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Implicit vs Explicit Animations
  2. matchedGeometryEffect for Hero Transitions
  3. Custom AnimatableModifier and Animatable
  4. TimelineView and Canvas for High-Performance Drawing
← Back to Swift Academy