Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SwiftUI – Background color for view of tab item

Whenever I click on a tab on tabview, it opens a view. I wish to change the background color of that view. Doesn’t matter what I do, it always stays white. Please look at the code and screenshot below:

Note: In the screenshot below, ignore positioning of the tab bar. In my actual app it shows at the bottom, but due to lot of code, I just created a sample app.

How can I set the background to gray and how can I remove the line/separator highlighted in the screenshot?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Code:

import SwiftUI
import Foundation

struct ContentView: View {
    static let sliderHandleHeight: CGFloat = 15.0
    static let radius: CGFloat = 16
    @State private var tabViewPanelMinHeight: CGFloat = 250.0
    @State private var tabViewPanelMaxHeight: CGFloat = 750.0
    @State private var tabViewPanelCurrentHeight: CGFloat = 250.0
    
    var body: some View {
        GeometryReader { geometry in
            VStack {
                Image(systemName: "touchid").resizable().scaledToFit()
            }
            .onAppear {
                tabViewPanelMinHeight = geometry.size.height * 0.25
                tabViewPanelMaxHeight = geometry.size.height * 0.91
                tabViewPanelCurrentHeight = tabViewPanelMinHeight
            }
            .overlay(alignment: .bottom) {
                VStack {
                    RoundedRectangle(cornerRadius: 5.0)
                        .foregroundColor(.secondary)
                        .frame(width: 50, height: 7.0)
                        .frame(height: ContentView.sliderHandleHeight)
                        .padding(.top, 5.0)
                        .simultaneousGesture(tap)
                    BottomTabBarView()
                }
                .background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
                .cornerRadius(ContentView.radius)
                .shadow(radius: 10)
                .frame(width: geometry.size.width, height: tabViewPanelCurrentHeight + ContentView.sliderHandleHeight, alignment: .bottom)
            }
        }
    }
    
    var tap: some Gesture {
        TapGesture(count: 1).onEnded {
            tabViewPanelCurrentHeight = ((tabViewPanelCurrentHeight == tabViewPanelMinHeight) ? tabViewPanelMaxHeight : tabViewPanelMinHeight)
        }
    }
}

enum Tab: String, CaseIterable {
    case none
    case profile
    case search
}

struct BottomTabBarView: View {
    @State var activeTab = Tab.search

    var body: some View {
        TabView(selection: $activeTab) {
            Group {
                Text("Profile")
                    .tabItem {
                        Label("Profile", systemImage: "square.text.square.fill")
                    }
                    .tag(Tab.profile)
                SearchExploreModalView()
                    .tabItem {
                        Label("Search", systemImage: "magnifyingglass")
                        Text("Search")
                    }
                    .tag(Tab.search)
            }
        }
        .background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
        .shadow(color: .black.opacity(0.3), radius: 0, x: 0, y: -0.5)
        .onAppear {
            let appearance = UITabBarAppearance()
            UITabBar.appearance().scrollEdgeAppearance = appearance
        }
    }
}

struct SearchExploreModalView: View {
    var body: some View {
        VStack {
            Text("Hello World")
        }
        .background(Color.gray)
    }
}

Screenshot:

enter image description here

>Solution :

To make the grey color the entire background of the tab, just allow the VStack containing the Text expand infinitely:

struct SearchExploreModalView: View {
    var body: some View {
        VStack {
            Text("Hello World")
        }
        // here:
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.gray)
    }
}

The "line" that you see is part of the shadow you added to TabView:

.shadow(color: .black.opacity(0.3), radius: 0, x: 0, y: -0.5)

Removing this line removes the line.

If you actually want the background of the tab to continue beyond the "grabber", use a ZStack instead of VStack:

ZStack(alignment: .top) {
    BottomTabBarView()

    RoundedRectangle(cornerRadius: 5.0)
        .foregroundColor(.secondary)
        .frame(width: 50, height: 7)
        .frame(height: ContentView.sliderHandleHeight)
        .padding(.top, 5.0)
        .simultaneousGesture(tap)
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.cornerRadius(ContentView.radius)
.shadow(radius: 10)
.frame(width: geometry.size.width, height: tabViewPanelCurrentHeight + ContentView.sliderHandleHeight, alignment: .bottom)

Output:

enter image description here

This might cause the "grabber" to overlap with some of the tabs’ contents. To avoid this, you can add a Spacer with height ContentView.sliderHandleHeight at the start of each tab.

That said, are you trying to reinvent sheet?

.sheet(isPresented: .constant(true)) {
    BottomTabBarView()
        .presentationDetents([.medium, .large])
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading