Programmatically change TabViewCustomization for iOS 18/iPad?

I have a TabView with a TabViewCustomization var, with customizationIDs set for all tabs. I have one tab set to .defaultVisibility(.hidden, for: .tabBar, .sidebar). This works as expected; initially, that tab isn't visible in either the tabBar or sidebar; with the sidebar open, I can click Edit and toggle the visibility. So far, so good.

Is there a way that I can programmatically change the visibility? For example, folks with the Admin role should see the tab by default, while those with the User role shouldn't.

If this is possible, can I hide the Edit button on the sidebar so the visibility can only be changed programmatically?

Answered by DTS Engineer in 817657022

@htolino_dmu Currently there isn't a recommended way to hide the edit button in the sidebar in this case. Another approach you can consider here is to introduce an enum for the various user roles and place the tabs behind a user flag.

For example:

enum MyTab: Hashable {
    case home
    case reports
    case browse
    case admin
}
enum UserRole {
    case admin
    case user
}

struct ContentView: View {
    @AppStorage("MyAppTabViewCustomization")
    private var customization: TabViewCustomization
    @State private var selection: MyTab = .home
    @State private var userRole: UserRole = .user


    var body: some View {
       
        TabView(selection: $selection) {
            Tab("Home", systemImage: "house", value: MyTab.home) {
                    Color.red
               }
               .customizationID("com.myApp.home")
            
               if userRole == .admin {
                   Tab("Admin Tools", systemImage: "wrench", value: MyTab.admin) {
                       Color.red
                   }
                   .customizationID("com.myApp.admin")
                   
                   Tab("Reports", systemImage: "chart.bar", value: MyTab.reports) {
                       Color.red
                   }
                   .customizationID("com.myApp.reports")
               }
               
               Tab("Browse", systemImage: "list.bullet", value: MyTab.browse) {
                   Color.red
               }
               .customizationID("com.myApp.browse")

        }
        .tabViewStyle(.sidebarAdaptable)
        .tabViewCustomization($customization)
    }
}

OK, so I used customization[sidebarVisibility: "Tab.adminTab"] = .visible or .hidden inside my onChange, and that seems to work. Still have to hide the Edit button in the sidebar.

Accepted Answer

@htolino_dmu Currently there isn't a recommended way to hide the edit button in the sidebar in this case. Another approach you can consider here is to introduce an enum for the various user roles and place the tabs behind a user flag.

For example:

enum MyTab: Hashable {
    case home
    case reports
    case browse
    case admin
}
enum UserRole {
    case admin
    case user
}

struct ContentView: View {
    @AppStorage("MyAppTabViewCustomization")
    private var customization: TabViewCustomization
    @State private var selection: MyTab = .home
    @State private var userRole: UserRole = .user


    var body: some View {
       
        TabView(selection: $selection) {
            Tab("Home", systemImage: "house", value: MyTab.home) {
                    Color.red
               }
               .customizationID("com.myApp.home")
            
               if userRole == .admin {
                   Tab("Admin Tools", systemImage: "wrench", value: MyTab.admin) {
                       Color.red
                   }
                   .customizationID("com.myApp.admin")
                   
                   Tab("Reports", systemImage: "chart.bar", value: MyTab.reports) {
                       Color.red
                   }
                   .customizationID("com.myApp.reports")
               }
               
               Tab("Browse", systemImage: "list.bullet", value: MyTab.browse) {
                   Color.red
               }
               .customizationID("com.myApp.browse")

        }
        .tabViewStyle(.sidebarAdaptable)
        .tabViewCustomization($customization)
    }
}

Much cleaner and easier to maintain. Thank you!

Programmatically change TabViewCustomization for iOS 18/iPad?
 
 
Q