Horizontal Menu in SwiftUI

In this post, we’ll learn how to build a horizontal menu similar to the one used in the Medium mobile application, like this:

The code is:

struct MenuSwiftUIView: View {
    var days = ["Monday", "Tuesday", "Wednesday", "Thursday",
    "Friday", "Saturday", "Sunday"]
    @State var selected = 0
    var body: some View {
        VStack {
            ScrollView(.horizontal) {
                HStack(spacing: 0) {
                    ForEach(Array(days.enumerated()), id: \.offset) {  index, day in
                        VStack {
                            Text(day).padding(5)
                                .foregroundStyle(.white)
                            if selected == index {
                                Color(.white)
                                    .frame(height: 2)
                            } else {
                                Color(.gray)
                                    .frame(height: 1)
                            }
                                
                        }.onTapGesture {
                            selected = index
                        }
                    }
                }
            }.scrollIndicators(ScrollIndicatorVisibility.hidden)
            Spacer() // Here what you want show considering the selected value
        }.padding()
        .background(.black)
    }
}

We define an array of strings that contains the menu options and a variable selected to store the value of the selected index in the menu.

The menu is built using a ScrollView that scrolls horizontally. In this, we add the Text that shows the label and the bottom line.

The HStack has spacing set to zero to avoid space between the bottom lines.

To have the index of the elements, we create a collection of indices and elements with Array(days.enumerated())

[(offset: 0, element: "Monday"), (offset: 1, element: "Tuesday"), (offset: 2, element: "Wednesday"), (offset: 3, element: "Thursday"), (offset: 4, element: "Friday"), (offset: 5, element: "Saturday"), (offset: 6, element: "Sunday")]

We hide the scrollbar in this way:

.scrollIndicators(ScrollIndicatorVisibility.hidden)

The line (indicator) changes color depending on the selected item.

For the last step, we can extract the ScrollView to create a reusable component:

struct HorizontalMenu: View {
    var labels: Array<String> = []
    var defaultColor = Color.gray
    var selectedColor = Color.white
    var textColor = Color.white
    
    @Binding var selected: Int
    
    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 0) {
                ForEach(Array(labels.enumerated()), id: \.offset) {  index, label in
                    VStack {
                        Text(label).padding(5)
                            .foregroundStyle(textColor)
                        if selected == index {
                            selectedColor
                                .frame(height: 2)
                        } else {
                            defaultColor
                                .frame(height: 1)
                        }
                        
                    }.onTapGesture {
                        selected = index
                    }
                }
            }
        }.scrollIndicators(ScrollIndicatorVisibility.hidden)
    }
}

Note that we bind the selected variable because we need to use its value in the main view.

Thus, the code becomes:

struct MenuSwiftUIView: View {
    var days = ["Monday", "Tuesday", "Wednesday", "Thursday",
    "Friday", "Saturday", "Sunday"]
    @State var selected = 0
    var body: some View {
        VStack {
            HorizontalMenu(labels: days, selected: $selected)
            Spacer() // Here what you want show considering the selected value
        }.padding()
        .background(.black)
    }
}

(Blog image from unsplash)

share this post with friends

Picture of Nicola De filippo

Nicola De filippo

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve

Leave a comment

Your email address will not be published. Required fields are marked *

Who I am

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve.

Follow Me Here

Get The Latest Updates

Periodically receive my super contents on coding and programming

join the family;)

Recent Posts