How to Create an Animated Navigation Menu in SwiftUI Using matchedGeometryEffect

One reason why I really enjoy programming using the SwiftUI framework is that it makes so easy to animate view changes. In particular, the introduction of the matchedGeometryEffect modifier, introduced in iOS 14, further simplifies the implementation of view animations. With matchedGeometryEffect, all you need is describe the appearance of two views. The modifier will then compute the difference between those two views and automatically animates the size/position changes.

We have written a detailed tutorial on matchedGeometryEffect. I highly recommend you to check it out if this is the very first time you come across this modifier. In this tutorial, we will make use of matchedGeometryEffect to develop an animated navigation menu like the one shown below.


Editor’s Note: To dive deeper into SwiftUI animation and learn more about the SwiftUI framework, you can check out the book here.

Creating the Navigation Menu

Before we create the animated menu, let’s start by creating the static version. As an example, the navigation menu only displays three menu items.


To layout three text views horizontally with equal spacing, we use the HStack view and Spacer to arrange the views. Here is the code sample:

As you can see from the code above, it contains quite a lot of duplications. It can be further simplified with ForEach:

We added a state variable named selectedIndex to keep track of the selected menu item. When the menu item is selected, we highlight it in purple. Otherwise, its background color is set to light gray.

To detect users’ touch, we attached the .onTapGesture modifier to the text view. When it’s tapped, we update the value of selectedIndex to highlight the selected text view.

Animating the Navigation Menu

Now that we’ve implemented the navigation menu, however, it misses the required animation. To animating the view change whenever a menu item is selected, all we need to do is create a namespace variable and attach the matchedGeometryEffect modifier to the text view in purple:

The ID and namespace are used for identifying which views are part of the same transition. We also need to attach the .animation modifier to the HStack view to enable the view animation. Note that this project is built using Xcode 13. The animation modifier is updated in the new version of iOS. You have to provide the value to monitor for changes. Here, it’s the selectedIndex.

Once you made the changes, you can test the NavigationMenu view in a simulator. Tap a menu item and you will see a nice animation when the item is transited from one state to another.


Using the Animated Navigation Menu View

To apply this animated navigation menu to your project, you can modify the NavigationMenu view to accept a binding to the selected index:

For example, you have created a page-based tab view like this:

You can add the NavigationMenu view as an overlay and use your own menu items.

Debugging Out of Memory Issues: Catching Layout Feedback Loop with the Runtime Magic
How USDZ Enables New Experiences for ARKit
What’s New in Natural Language APIs in iOS 13