Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested TabView - Remove inner tab bar iOS 13, Swift UI

I am using a TabView to represent three tabs. In iOS 14, this is handled nicely, but iOS 13 results in a gray bottom bar which is the tab bar for navigation. How can I remove this bar?

Please bear in mind that this is a TabView within a TabView. The outer TabView's bar is shown at the bottom with five tabs; the inner TabView bar I do not want shown at all.

The code below represents the inner TabView.

import SwiftUI

struct DashboardView: View {
    @State private var pageIndex = 1
    
    var body: some View {
        VStack {
            DashboardTopBar(index: $pageIndex) // A custom selected tab indicator
            if #available(iOS 14.0, *) {
                TabView(selection: $pageIndex) {
                    RehabView().tag(0)
                    PerformanceView().tag(1)
                    RecoveryView().tag(2)
                }
                .tabViewStyle(PageTabViewStyle())
                .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
            } else {
                TabView(selection: $pageIndex) {
                    RehabView().tag(0)
                    PerformanceView().tag(1)
                    RecoveryView().tag(2)
                }
            }
        }
    }
}

The image below shows iOS 13 on the left and iOS 14 on the right.

Left: iOS 13, Right: iOS 14

Minimal, Complete, and Verifiable Example

If the code below is launched on iOS 13, you will note a tab bar on the bottom and an empty tab bar on top of it.

import SwiftUI

struct ContentView: View {
    @State private var outerTabViewSelectedTab = 0
    @State private var innerTabViewSelectedTab = 1
    var body: some View {
        TabView(selection: $outerTabViewSelectedTab,
                content:  {
                    Text("Outer 1").tabItem { Text("Outer 1") }.tag(1)
                    TabView(selection: $innerTabViewSelectedTab,
                            content:  {
                                Text("Inner 1").tag(1)
                                Text("Inner 2").tag(2)
                            }).tabItem { Text("Outer 2") }.tag(2)
                })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
like image 666
McGuile Avatar asked Sep 22 '20 09:09

McGuile


1 Answers

Hide it explicitly... as it is for backward compatibility it is safe, because behavior is already known and won't change.

So here is a solution

var body: some View {
    TabView(selection: $outerTabViewSelectedTab,
            content:  {
                Text("Outer 1").tabItem { Text("Outer 1") }.tag(1)
                TabView(selection: $innerTabViewSelectedTab,
                        content:  {
                            Text("Inner 1").tag(1)
                             .background(TabBarAccessor { tabBar in
                                tabBar.isHidden = true
                             })
                            Text("Inner 2").tag(2)
                        }).tabItem { Text("Outer 2") }.tag(2)
            })
}

Used TabBarAccessor from my other solution in https://stackoverflow.com/a/59972635/12299030

backup

like image 154
Asperi Avatar answered Dec 01 '22 17:12

Asperi