Search code examples
swiftswiftuitabbar

SwiftUI - custom TabBar height based on device


enter image description here

I am trying to set up the height of my custom TabBar based on Device, my code:

struct MyTabBar: View {
    @Binding var index: Int

    var body: some View {
        HStack {
            Button(action: {
                self.index = 0
            }) {
                Image(ImageText.iconHome.image)
            }

            Spacer(minLength: 0)

            Button(action: {
                self.index = 1
            }) {
                Image(ImageText.iconBell.image)
            }

            Spacer(minLength: 0)

            Button(action: {
                self.index = 2
            }) {
                Image(ImageText.iconAdd.image)
            }

            Spacer(minLength: 0)

            Button(action: {
                self.index = 3
            }) {
                Image(ImageText.iconSearch.image).foregroundColor(Color.red)
            }

            Spacer(minLength: 0)

            Button(action: {
                self.index = 4
            }) {
                Image(ImageText.iconHamburger.image)
            }

        }.padding(.horizontal, 26).frame(height: 56)
    }
}

If the devices have notch, how can I set my custom TabBar to have higher height? Does SwiftUI have something that can be useful here?


Solution

  • You can use the GeometryReader element to access the safe area insets, and add it as a padding using .safeAreaInsets.bottom (note that the Xcode autocompletion is almost never working on GeometryProxy properties):

    var body: some View {
        GeometryReader { proxy in
            VStack {
                // Content goes here
                Spacer()
    
                // Custom tab bar
                HStack {
                    Spacer()
                    Button(action: {}) {
                        Image(systemName: "house.fill")
                        .padding()
                    }
                    Spacer()
                    Button(action: {}) {
                        Image(systemName: "house.fill")
                        .padding()
                    }
                    Spacer()
                    Button(action: {}) {
                        Image(systemName: "house.fill")
                        .padding()
                    }
                    Spacer()
                    Button(action: {}) {
                        Image(systemName: "house.fill")
                        .padding()
                    }
                    Spacer()
                }
                .padding(.bottom, proxy.safeAreaInsets.bottom)
                .background(Color.red)
    
            }
        }.edgesIgnoringSafeArea(.bottom)
    }