Expandable Button in SwiftUI

Create an animated expandable button using SwiftUI

Ale Patrón
Aug 7 · 3 min read
Image for post
Image for post
The expandable button we will be building.

Note: This tutorial is also available in video form on YouTube.

In a previous article, I showed you how to build an expandable button with Swift and UIKit. With SwiftUI gaining traction, I decided to share an updated article showing how we can implement this same functionality using SwiftUI.

Implementing custom views with SwiftUI is extremely simple, and we will leverage its power to build an expandable button that will look like the one below:

Image for post
Image for post
Animated expandable button.

Our buttons will simply need to be embedded in a VStack. Whenever the primary button is tapped, we will either show or hide the secondary buttons, signaled in the diagram below, depending on their current state.

ExpandableButtonPanel view hierarchy.

Let’s start by creating a custom struct called ExpandableButtonItem, which will be used to represent the content for each of the buttons in our button panel. The ExpandableButtonItem will include a label to show on the button (an emoji String in our case) and an optional action that is executed whenever the button is tapped. We also have an id in order to conform to the Identifiable protocol.

Then we’ll create another custom struct called ExpandableButtonPanel with two instance properties, primaryItem and secondaryItems. The primaryItem corresponds to the button that is always visible. The secondaryItems is a list correspond to each of the buttons that will be shown or hidden when the primary button is tapped.

We will first embed the buttons for each of the secondaryItems in a VStack, and the button for the primaryItem last.

To show and hide the secondary buttons, we will add a State boolean––isExpanded––to keep track of the current expanded state. The isExpanded boolean will be toggled whenever the primary button is tapped, causing the frame of each secondary button to change to handle showing/hiding.

To animate the panel, all we need to do is embed the call to toggle isExpanded inside a withAnimation block. This will automatically cause our secondary buttons to animate, since their frames depend on the isExpanded State. In the end, our ExpandableButtonPanel struct will look similar to this:

You may notice I also added some styling to our panel by changing its background color, its corner radius (for rounded corners), its font size, and its shadow. Feel free to modify this as you like.

To use an ExpandableButtonPanel, we can now do something like this:

ExpandableButtonPanel(              
primaryItem: ExpandableButtonItem(label: "➕"), // No action
secondaryItems: [
ExpandableButtonItem(label: "🌞") {
// Can add action, if necessary
},
ExpandableButtonItem(label: "🥑") {
// Can add action, if necessary
}
]
)

We can also use our expandable button as a Floating Action Button (FAB). To achieve this, we can embed our main view’s content on a ZStack, making sure that the ExpandableButtonPanel is the top-most subview. We can embed the ExpandableButtonPanel in a VStack and/or HStack and use a Spacer to achieve any positioning we want. For example, if we want the FAB to be on the bottom right corner of our screen, we can do something like so:

If we run our app, we should see the following result:

Image for post
Image for post

Thanks for reading! I hope you found this article useful. You can find a finished demo on GitHub.

The Startup

Medium's largest active publication, followed by +720K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store