Animated FAB Menu in SwiftUI

DevTechie Inc
Jun 11, 2022

Photo by Kelly Sikkema on Unsplash

SwiftUI makes user interface development easy, not only that it makes it fun. Today, we will build out FAB(Fast Action Button) menu with animation 😃

Here is what we will build.

Let’s start with a navigationView so we can have navigationTitle for the view. We will also add a static List to display couple of DevTechie courses.

struct FABMenu: View {
    @State private var showMenu = false
    var body: some View {
        NavigationView {
                List {
                    Text("Mastering SwiftUI")
                    Text("iOS App Development in UIKit")
                }
                .navigationTitle("DevTechie Courses")
        }
    }
}
Since FAB is always visible, we will put it on ZStack and move our List inside the ZStack. We will also set ZStack alignment to .bottomTrailing so FAB is tucked away at the bottom corner.

struct FABMenu: View {
    @State private var showMenu = false
    var body: some View {
        NavigationView {
            ZStack(alignment: .bottomTrailing) {
                List {
                    Text("Mastering SwiftUI")
                    Text("iOS App Development in UIKit")
                }
            }.font(.title)
                .navigationTitle("DevTechie Courses")
        }
    }
}
Now, its time to add menu buttons. We will start with + button which will open the menu. When the menu is open, we will rotate button 45 degrees so it looks like a X symbol to close the menu.

We will throw button inside a group so we can apply some common modifiers to them like padding in trailing and bottom sides and animation modifier to animate button states.

struct FABMenu: View {
    @State private var showMenu = false
    var body: some View {
        NavigationView {
            ZStack(alignment: .bottomTrailing) {
                List {
                    Text("Mastering SwiftUI")
                    Text("iOS App Development in UIKit")
                }
                
                Group {
                    Button(action: { showMenu.toggle() }) {
                        Image(systemName: "plus")
                            .padding()
                            .rotationEffect(.degrees(showMenu ? 45 : 0))
                    }
                    .foregroundColor(.white)
                    .background(Circle().fill(Color.orange))
                    
                }
                .padding(.trailing)
                .padding(.bottom)
                .animation(.easeInOut, value: showMenu)
            }.font(.title)
                .navigationTitle("DevTechie Courses")
        }
    }
}
Next, we will add rest of the buttons and offset them in y-axis. Initially buttons will be hidden so they are not visible and as State property called “showMenu” toggles its state, visibility, rotation and offset will animate.

struct FABMenu: View {
    @State private var showMenu = false
    var body: some View {
        NavigationView {
            ZStack(alignment: .bottomTrailing) {
                List {
                    Text("Mastering SwiftUI")
                    Text("iOS App Development in UIKit")
                }
                
                Group {
                    Button(action: { showMenu.toggle() }) {
                        Image(systemName: "plus")
                            .padding()
                            .rotationEffect(.degrees(showMenu ? 45 : 0))
                    }
                    .foregroundColor(.white)
                    .background(Circle().fill(Color.orange))
                    
                    
                    Button(action: { showMenu.toggle() }) {
                        Image(systemName: "power")
                            .padding()
                            .rotationEffect(.degrees(showMenu ? 0 : -180))
                    }
                    .foregroundColor(.white)
                    .background(Circle().fill(Color.pink))
                    .offset(y: showMenu ? -70 : 0)
                    .opacity(showMenu ? 1 : 0)
                    
                    Button(action: { showMenu.toggle() }) {
                        Image(systemName: "moon.circle.fill")
                            .padding()
                            .rotationEffect(.degrees(showMenu ? 0 : -180))
                    }
                    .foregroundColor(.white)
                    .background(Circle().fill(Color.teal))
                    .offset(y: showMenu ? -150 : 0)
                    .opacity(showMenu ? 1 : 0)
                }
                
                .padding(.trailing)
                .padding(.bottom)
                .animation(.easeInOut, value: showMenu)
            }.font(.title)
                .navigationTitle("DevTechie Courses")
        }
    }
}
Final output:


With that we have reached the end of this article. Don’t forget to subscribe to our newsletter at https://www.devtechie.com