http-redirectswiftuinavigationsidebartabbar

Bottom Tab Bar is not visible in all the pages


The below are my sidebar view and bottom tab bar view..The tab bar is visible only in the views that is associated with that(I mean home, search, profile and settings but it is visible in the pages that are redirecting from here)…but not visible in the other that is given in the side bar view. So what is the possible way to show the tab bar in all of the views both in the tab bar and the views given in the side bar.

Side bar View :

struct SidebarView: View {

@Environment(\.presentationMode) var presentationMode

@State private var isDropdownOpen = false

@State private var isTicketsPagePresented = false

@State private var isParkMapPopupPresented = false

@State private var ticketsPageOffset: CGSize = .zero

@State private var date: String = ""

@State private var time: String = ""

@State private var adultCount: Int = 0

@State private var childCount: Int = 0

@EnvironmentObject var layoutDirectionManager: LayoutDirectionManager

@State private var isSidebarOpen = false

var body: some View {
    GeometryReader { geometry in
        VStack(alignment: .leading, spacing: 20) {
            ScrollView(showsIndicators: false) {
                ZStack(alignment: .leading) {
                    RoundedRectangle(cornerRadius: 33)
                        .fill(Color("welcomebg"))
                        .frame(width: 320, height: isDropdownOpen ? 155 : 60, alignment: .center)
                        .shadow(radius: 0.8)
                        .background(Color.white)
                        .padding(.leading, 10)
                    
                    Group {
                        HStack(alignment: .center, spacing: 125) {
                            Text("welcome".localized)
                                .foregroundColor(Color("welcometext"))
                                .font(Font.custom(Singleton.shared.setBoldCustomFont("Hobeaux-bold"), size: 20))
                                .offset(y: isDropdownOpen ? -30 : 0)
                                .padding(.leading, 10)
                            
                            Button(action: {
                                isDropdownOpen.toggle()
                            }) {
                                HStack {
                                    Text(Singleton.shared.retrieveString(for: .selectedLanguage) == LanguageEnum.arabic.languageCode ? LanguageEnum.arabic.title : LanguageEnum.english.title)
                                    Image(systemName: isDropdownOpen ? "chevron.up" : "chevron.down")
                                }
                                .foregroundColor(.black)
                                .font(.system(size: 18))
                                .fontWeight(.light)
                            }
                            .offset(x : Singleton.shared.retrieveString(for: .selectedLanguage) == "en" ? 0 : 50 ,y: isDropdownOpen ? -30 : 0)
                        }
                        .padding(.horizontal, 15)
                        
                        if isDropdownOpen {
                            Divider().frame(width: 260,height: 0.5).overlay(.black).padding(.horizontal, 25)
                            
                            VStack(alignment: .leading, spacing: 8) {
                                ForEach(0..<Singleton.shared.languages.count, id: \.self) { index in
                                    Text(Singleton.shared.languages[index])
                                        .font(.system(size: 20))
                                        .padding(.top, 10)
                                        .onTapGesture {
                                            Singleton.shared.storeString(value: Singleton.shared.languages[index] == LanguageEnum.english.title ?  LanguageEnum.english.languageCode : LanguageEnum.arabic.languageCode, in: .selectedLanguage)
                                            layoutDirectionManager.toggleLayoutDirection()
                                            isDropdownOpen.toggle()
                                        }
                                }
                            }
                            .padding(.top, 75)
                            .padding(.horizontal, 30)
                        }
                    }
                }
                .padding(.top, 10)
                
                VStack(alignment: .leading, spacing: 15) {
                    let menuItems: [(String, AnyView)] = [
                        (“Page”1.localized, TicketsPage()),
                        (“Page”2, AnyView(RigView().navigationBarBackButtonHidden())),
                    ]
                    ForEach(menuItems, id: \.0) { menuItem in
                        if menuItem.0 == "book_tickets".localized {
                            Button(action: {
                                self.isTicketsPagePresented = true
                            }) {
                                Text(menuItem.0)
                                    .foregroundColor(Color("menucolor"))
                                    .font(Font.custom(Singleton.shared.setMediumCustomFont("DMSans-Medium"), size: 20))
                                    .padding(.top, 10)
                            }
                            .alignmentGuide(.leading) { _ in 270 }
                        } else if menuItem.0 == "park_map".localized {
                            Button(action: {
                                isParkMapPopupPresented.toggle()
                                presentationMode.wrappedValue.dismiss()
                            }) {
                                Text(menuItem.0)
                                    .foregroundColor(Color("menucolor"))
                                    .font(.system(size: 18))
                                    .padding(.top, 10)
                            }
                            .alignmentGuide(.leading) { _ in 270 }
                        } else {
                            NavigationLink(destination: menuItem.1) {
                                Text(menuItem.0)
                                    .foregroundColor(Color("menucolor"))
                                    .font(.system(size: 18))
                                    .padding(.top, 10)
                            }
                            .alignmentGuide(.leading) { _ in 270 }
                        }
                    }
                    .fullScreenCover(isPresented: $isParkMapPopupPresented) {
                        ParkMap()
                            .presentationBackground(Color.black.opacity(0.65))
                    }
                }
                Spacer()
                    .frame(height: max(0, geometry.size.height - 700))
            }
        }
        .foregroundColor(Color("menucolor"))
        .font(Font.custom(Singleton.shared.setSemiBoldCustomFont("DMSans-Medium"), size: 20))
        .fontWeight(.semibold)
        .sheet(isPresented: $isTicketsPagePresented) {
            TicketsPage()
        }
    }
}

}

Tab bar view :

struct TabBar: View {

@State var selectedTab = 0

@State private var contentID = UUID()

@State private var date: String = ""

@State private var adult: Int = 0

@State private var child: Int = 0

@State private var isTicketSheetPresented = false

@State private var shouldResetHome = false

@State private var isSidebarOpen = false

var body: some View {
    NavigationView {
        ZStack(alignment: .bottom) {
            TabView(selection: $selectedTab) {
                Home()
                    .tag(0)
                    .id(contentID)
                
                SearchView(selectedTab: $selectedTab)
                    .tag(1)
                
                Profile()
                    .tag(3)
                
                Settings()
                    .tag(4)
                
            }
            
            .onChange(of: selectedTab, perform : {
                value in
                DispatchQueue.main.async {
                    self.contentID = UUID()
                }
                if value == 2 {
                    isTicketSheetPresented = true
                }
            })
            
            .onChange(of: isTicketSheetPresented) { newValue in
                if newValue == false {
                    selectedTab = 0
                }
            }
            
            TabBarShape(insetRadius: 25)
                .frame(width: 360, height: 72)
                .foregroundColor(.white)
                .shadow(color: Color(white: 0.8), radius: 6, x: 0, y: 3)
                .offset(y: 20)
            
            Button {
                selectedTab = 2
            } label: {
                CustomTabItem(imageName: "ticket", title: "Ticket", isActive: (selectedTab == 2))
            }
            .frame(width: 55, height: 55, alignment: .center)
            .background(LinearGradient(colors: [Color("lg31"), Color("lg32")], startPoint: .top, endPoint: .bottom))
            .clipShape(Circle())
            .shadow(radius: 0.8)
            .offset(y: -35)
            
            HStack(alignment: .center) {
                ForEach(TabbedItems.allCases, id: \.self) { item in
                    if item != .ticket {
                        Button {
                            if item == .home {
                                shouldResetHome.toggle()
                            }
                            if selectedTab == item.rawValue {
                                DispatchQueue.main.async {
                                    self.contentID = UUID()
                                }
                            }
                            selectedTab = item.rawValue
                        } label: {
                            CustomTabItem(imageName: item.iconName, title: item.title, isActive: (selectedTab == item.rawValue))
                        }
                    }
                }
            }
            
            .blur(radius: isSidebarOpen ? 2 : 0)
            
            .sheet(isPresented: $isTicketSheetPresented) {
                TicketsPage(date: $date, adultCount: $adult, childCount: $child)
                    .presentationBackground(.clear)
            }
            
            if isSidebarOpen {
                SidebarView()
                    .frame(width:UIScreen.main.bounds.width / 1.17)
                    .background(Color.white)
                    .transition(.move(edge: .leading))
                    .onTapGesture {
                        withAnimation {
                            self.isSidebarOpen.toggle()
                        }
                    }
                    .offset(x: UIScreen.main.bounds.width - 420)
            }
        }
        .ignoresSafeArea(.keyboard, edges: [.bottom, .top])
        .toolbar {
            ToolbarItem(placement: .primaryAction) {
                HStack(alignment: .center, spacing: 250) {
                    Image("LaunchImage")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 55, height: 55)
                    Button(action: {
                        withAnimation {
                            self.isSidebarOpen.toggle()
                        }
                        print("Menu Button Tapped")
                        
                    }) {
                        Image(isSidebarOpen ? "close" : "menu")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 35, height: 35)
                            .padding(.bottom, 3)
                    }
                }
            }
        }
    }
}
func CustomTabItem(imageName: String, title: String, isActive: Bool) -> some View {
    HStack(spacing: 0) {
        Spacer(minLength: 15)
        if imageName == "ticket" {
            LottieView(loopMode: .loop, fileName: "ticket")
                .frame(width: 40, height: 40, alignment: .center)
        } else {
            Image(imageName)
                .resizable()
                .renderingMode(.template)
                .foregroundColor(imageName == "ticket" ? .white : (isActive ? .purple : Color("tabitem")))
                .frame(width: 23, height: 23, alignment: .center)
                .padding(5)
        }
        Spacer(minLength: 15)
    }
}

}


Solution

  • SideBarView is NOT a subview of TabView. You're expecting an illegitimate behavior.

    1. To achieve this you might want to add the SideBarView to every subview in TabView. You can achieve this by creating a TabItemView that gets a content block and a adds the SideBarView.

    struct TabViewItem<Content: View>: View {
        
        // This is your TabViewItem (home, search, profile or settings)
        @ViewBuilder let content: () -> Content
        
        @State private var isSidebarOpen = false
        
        var body: some View {
            ZStack {
                content()
                
                if isSidebarOpen {
                    SidebarView()
                }
            }
        }
    }
    

    Usage:

    TabView(selection: $selectedTab) {
        TabViewItem {
            Home()
        }
        .tag(0)
        .id(contentID)
        
        TabViewItem {
            SearchView(selectedTab: $selectedTab)
        }
        .tag(1)
        
        TabViewItem {
            Profile()
        }
        .tag(3)
        
        TabViewItem {
            Settings()
        }
        .tag(4)
    }
    

    2. You can also achieve this by creating a custom ViewModifier that adds an overlay layer to every subview of TabBar.

    struct SideBar: ViewModifier {
        @Binding var open: Bool
        
        func body(content: Content) -> some View {
            content
                .overlay(alignment: .leading) {
                    if open {
                        SidebarView()
                    }
                }
        }
    }
    extension View {
        func sideBar(open: Binding<Bool>) -> some View {
            modifier(SideBar(open: open))
        }
    }
    

    Usage:

    TabView(selection: $selectedTab) {
        Home()
            .tag(0)
            .id(contentID)
            .sideBar(open: $isSidebarOpen)
        
        SearchView(selectedTab: $selectedTab)
            .tag(1)
            .sideBar(open: $isSidebarOpen)
        
        Profile()
            .tag(3)
            .sideBar(open: $isSidebarOpen)
        
        Settings()
            .tag(4)
            .sideBar(open: $isSidebarOpen)
    }