2

I consider whether there is possibility to add more Views to TabView in SwiftUI then there is place for TabItems.

I have done something like this:

 TabView(selection: $selectedTab) {
            Text("Hello World 1")
                .tabItem {
                    Image(systemName: "1.circle")
                    Text("Item 1")
                }.tag(0)

            Text("Hello World 2")
                .tabItem {
                    Image(systemName: "2.circle")
                    Text("Item 2")
                }.tag(1)

            Text("Hello World 3")
                .tabItem {
                    Image(systemName: "3.circle")
                    Text("Item 3")
                }.tag(2)

            Text("Hello World 4")
                .tabItem {
                    Image(systemName: "4.circle")
                    Text("Item 4")
                }.tag(3)

            Text("Hello World 5")
                .tabItem {
                    Image(systemName: "5.circle")
                    Text("")
                }.tag(4)

            Text("Hello World 5")
                .tabItem {
                    Image(systemName: "6.circle")
                    Text("")
                }.tag(5)
        }

And there is More 3-dots button displayed automatically. But I would like to not show this additional tab items in tab bar just first 4 or 5 items and other items will be only programatically navigated. I would like to do it this way to add then Hamburger Menu with buttons that will be switching this other views.

I know that Hamburger/Navigation Drawer/Side Menu is not what apples recommends but such design will fit my application requirements great. :)

Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143

1 Answers1

2

I hope the following approach would be useful. The idea is to have dynamic range which shows tab items depending on currently selected one.

For this demo selection, and including visible tabs, are changed depending on preview/next button, but it is not important - the of selection might be different, it just need update range of visible tabs depending on selected tab. That is it.

Here is how the demo behaves:

demo

struct ContentView: View {
    static let maxTabs = 8
    
    @State var selectedTab = 2
    @State var visibleTabs = [0, 1, 2, 3]
    var body: some View {
        VStack {
            self.selectorView
            Divider()
            TabView(selection: $selectedTab) {
                ForEach(visibleTabs, id: \.self) { i in
                    self.viewForTab(i)
                        .tabItem {
                            Image(systemName: "\(i).circle")
                            Text("Item \(i)")
                        }.tag(i)
                }
            }
        }
    }
    
    var selectorView: some View {
        HStack {
            Button(action: {
                let prev = self.selectedTab - 1
                if prev >= 0 {
                    if prev < self.visibleTabs.min()! {
                        self.visibleTabs = self.visibleTabs.map { $0 - 1 }
                    }
                    self.selectedTab = prev
                }
            }) {
                Text("< Prev").padding([.top, .horizontal])
            }.disabled(self.selectedTab == 0)
            Button(action: {
                let next = self.selectedTab + 1
                if next < Self.maxTabs {
                    if next > self.visibleTabs.max()! {
                        self.visibleTabs = self.visibleTabs.map { $0 + 1 }
                    }
                    self.selectedTab = next
                }
            }) {
                Text("Next >").padding([.top, .horizontal])
            }.disabled(self.selectedTab == Self.maxTabs - 1)
        }
    }
    
    private func viewForTab(_ tag: Int) -> some View {
        // Provide your view for requested tab tag
        Text("Hello World \(tag)")
    }
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Asperi
  • 228,894
  • 20
  • 464
  • 690