1

I am currently having trouble with my Custom Tab Bar there is a gray area above it (Tab View) that controls each tab but I need that to go under my custom tab bar but functionality of the TabView still be in effect and be used with the icons. You can hide the Tab bar with UITabBar.apperance() which gets rid of the gray area but no longer has any functions.. but I need that gray area to go under the tabs. If that makes sense?

Light gray area is the area i need under the icons. Thanks.

Home.swift

import SwiftUI

struct Home: View {
    
    //Hiding Tab Bar..
    init() {
        UITabBar.appearance().isHidden = false
    }
    
    var body: some View {
        
        VStack(spacing: 0){
            //Tab View...
            TabView{
                
                Color.blue
                    .tag("house.circle")
                
                Color.green
                    .tag("pencil")
                
                Color.pink
                    .tag("magnifyingglass")
                
                Color.red
                    .tag("bell")
                
                Color.yellow
                    .tag("cart")
            }

            //Custom Tab Bar...
            CustomTabBar()
        }
        .ignoresSafeArea()
    }
}

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
    }
}

//Extending View To Get Screen Frame...

extension View {
    func getRect()->CGRect {
        return UIScreen.main.bounds
    }
}

CustomTabBar.swift

import SwiftUI

struct CustomTabBar: View {
    
    var body: some View {
            HStack(spacing: 0){
                
                // Tab Bar Button...
                TabBarButton(systemName: "house.circle")
                    .background(Color.blue)
                
                TabBarButton(systemName: "pencil")
                    .background(Color.green)
                
                Button(action: {}, label: {
                        
                    Image(systemName: "magnifyingglass")
                            .resizable()
                            .renderingMode(.template)
                            .aspectRatio(contentMode: .fit)
                            .frame(width:24, height:24)
                            .foregroundColor(.white)
                            .padding(20)
                            .background(Color.green)
                            .clipShape(Circle())
                        //Shadows
                            .shadow(color: Color.black.opacity(0.05), radius: 5, x: 5, y: 5)
                            .shadow(color: Color.black.opacity(0.05), radius: 5, x: -5, y: -5)
                })
                .tag("magnifyingglass")
                
                TabBarButton(systemName: "bell")
                    .background(Color.red)
                TabBarButton(systemName: "cart")
                    .background(Color.yellow)
            }
            .padding(.top)
            //Decreasing the extra padding added...
            .padding(.vertical, -0)
            .padding(.bottom,getSafeArea().bottom == 0 ? 15 : getSafeArea().bottom)
            .background(Color.white)
    }
}

struct CustomTabBar_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}

//extending view to get safe area...
extension View {
    func getSafeArea()-> UIEdgeInsets {
        return UIApplication.shared.windows.first?.safeAreaInsets ?? UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
}

struct TabBarButton: View {
    
    var systemName: String
    
    var body: some View{
        Button(action: {
        }, label: {
            
            VStack(spacing: 8){
                
                Image(systemName)
                    .resizable()
                    //Since its asset image...
                    .renderingMode(.template)
                    .aspectRatio(contentMode: .fit)
                    .frame(width:28, height: 28)
            }
            .frame(maxWidth: .infinity)
        })
    }
}

EDIT: SECOND IMAGE I am hiding the tab bar setting it to true instead of false.

//Hiding Tab Bar..
    init() {
        UITabBar.appearance().isHidden = true
    }

KeyesCode
  • 115
  • 1
  • 13
  • You should create a [mre] so we can test your code. I'm still confused what you mean about the gray bit though - the default background of a tab bar? Then what do you mean by wanting it under the tabs, do you mean you want it clear/transparent? – George Sep 06 '21 at 01:39
  • There is a my icons the home, heart, search, bell, cart. Then above that in the picture there is a gray box area. That box area actually is functioning to the tab view. I need that to go under the icons so that when the icons are clicked the tab view switches. – KeyesCode Sep 06 '21 at 01:50
  • I edited my original question and showed the difference between the 2 pictures 1 with the tab box and the other without it. – KeyesCode Sep 06 '21 at 01:54
  • I really can't reproduce the issue. Please make a [mre], which anyone can copy & paste. Use SF Symbols, such as `house`, `heart`, `bell` and `cart` to create your example if you would like. – George Sep 06 '21 at 01:58
  • I made it minimal reproducible for you. If you click the background colors it does not change the view color. But if you click above it in the gray area you'll see that it changes the color of the view. – KeyesCode Sep 06 '21 at 03:14

1 Answers1

0

you could try this to "cover" the original TabView bar:

In Home replace VStack with ZStack.

and

struct CustomTabBar: View {
    
    var body: some View {
        VStack (alignment: .leading) {
            Spacer()
            HStack(spacing: 0) {
                TabBarButton(systemName: "house.circle").background(Color.blue)
                TabBarButton(systemName: "pencil").background(Color.green)
                Button(action: {}, label: {
                    Image(systemName: "magnifyingglass")
                            .resizable()
                            .renderingMode(.template)
                            .aspectRatio(contentMode: .fit)
                            .frame(width:24, height:24)
                            .foregroundColor(.white)
                            .padding(20)
                            .background(Color.green)
                            .clipShape(Circle())
                        //Shadows
                            .shadow(color: Color.black.opacity(0.05), radius: 5, x: 5, y: 5)
                            .shadow(color: Color.black.opacity(0.05), radius: 5, x: -5, y: -5)
                })
                .tag("magnifyingglass")
                
                TabBarButton(systemName: "bell").background(Color.red)
                TabBarButton(systemName: "cart").background(Color.yellow)
            }
        }
            .padding(.bottom, getSafeArea().bottom == 0 ? 15 : getSafeArea().bottom)
            .background(Color.white)
    }
}

you will then need to implement the action of each of your CustomTabBar buttons.

EDIT1:

ok, as I mentioned you need to implement the actions for your buttons. There are many ways to do this, this is just one approach:

struct CustomTabBar: View {
    @Binding var tagSelect: String
    
    var body: some View {
        VStack (alignment: .leading) {
            Spacer()
            HStack(spacing: 0) {
                TabBarButton(tagSelect: $tagSelect, systemName: "house.circle").background(Color.blue)
                TabBarButton(tagSelect: $tagSelect, systemName: "pencil").background(Color.green)
                Button(action: {}, label: {
                    Image(systemName: "magnifyingglass")
                            .resizable()
                            .renderingMode(.template)
                            .aspectRatio(contentMode: .fit)
                            .frame(width:24, height:24)
                            .foregroundColor(.white)
                            .padding(20)
                            .background(Color.green)
                            .clipShape(Circle())
                        //Shadows
                            .shadow(color: Color.black.opacity(0.05), radius: 5, x: 5, y: 5)
                            .shadow(color: Color.black.opacity(0.05), radius: 5, x: -5, y: -5)
                })
                .tag("magnifyingglass")
                
                TabBarButton(tagSelect: $tagSelect, systemName: "bell").background(Color.red)
                TabBarButton(tagSelect: $tagSelect, systemName: "cart").background(Color.yellow)
            }
        }
        .padding(.bottom,getSafeArea().bottom == 0 ? 15 : getSafeArea().bottom)
        // no background or use opacity, like this
        .background(Color.white.opacity(0.01)) // <-- important
    }
}

extension View {
    func getSafeArea()-> UIEdgeInsets {
        return UIApplication.shared.windows.first?.safeAreaInsets ?? UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
}

struct TabBarButton: View {
    @Binding var tagSelect: String
    var systemName: String
    
    var body: some View{
        Button(action: {tagSelect = systemName }, label: {
            VStack(spacing: 8){
                Image(systemName)
                    .resizable()
                    .renderingMode(.template)
                    .aspectRatio(contentMode: .fit)
                    .frame(width:28, height: 28)
            }
            .frame(maxWidth: .infinity)
        })
    }
}
struct Home: View {
    @State var tagSelect = "house.circle"

    init() {
        UITabBar.appearance().isHidden = false
    }
    
    var body: some View {
        ZStack {
            TabView (selection: $tagSelect) {
                Color.blue.tag("house.circle")
                Color.green.tag("pencil")
                Color.pink.tag("magnifyingglass")
                Color.red.tag("bell")
                Color.yellow.tag("cart")
            }
            CustomTabBar(tagSelect: $tagSelect)
        }
        .ignoresSafeArea()
    }
}

extension View {
    func getRect()->CGRect {
        return UIScreen.main.bounds
    }
}