Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI how TabView is implemented underneath

I consider how TabView in SwiftUI has been implemented.

As I can see it takes in such just @ViewBuilder with content into initializer.

public init(selection: Binding<SelectionValue>?, @ViewBuilder content: () -> Content)

I would like to implement my own custom MyTabView which usage resembles usage of native TabView. But consider how it is possible to pass into content @ViewBuilder multiple views (screens) and then based on this parameter i.e. closure returning Content just display them conditionally! based on selection parameter.

Is there some private implementation or there is possibility to achieve this somehow. Original TabView has many limitations which I would like to circumvent. But simulenaously I would like to stick to native implemantation usage

I would like to have something like this approach:

MyTabView(selection: $selection, tabs: { 
    Tab1() 
    Tab2() 
    Tab3() 
}) { 
    View1()
    View2()
    View3() 
}

Of course the best would be to have something like this

MyTabView(selection: $selection}) { 
    View1().tabItem({})
    View2().tabItem()
    View3().tabItem() 
}

But the last option seems to be even harder to achieve

like image 838
Michał Ziobro Avatar asked Sep 13 '25 05:09

Michał Ziobro


1 Answers

Ok I have simple version that does have similar API like TabView. I've used Preferences and TupleView to achieve this.

The one thing that is currently unresolved is how to handle Groups.

Here is github project link https://github.com/michzio/Click5Menu

And here sample how it can be used:

 Click5MenuView {


            Page1()
            Page2()
            Page3()

            NavigationView {
                Text("Page 4")
                    .navigationBarTitle("Page 4", displayMode: .inline)
                    .hamburgerButton()
            }
            .menuItem {
               MenuItemView(systemImage: "person", title: "Page 4")
            }
            .withTag(3)

            NavigationView {
                Text("Page 5")
                .navigationBarTitle("Page 5", displayMode: .inline)
                .hamburgerButton()
            }
            .menuItem {
                MenuItemView(systemImage: "person", title: "Page 5")
            }
            .withTag(4)

}

struct Page1 : View {

    var body: some View {

        NavigationView {
            Text("Page 1")
            .navigationBarTitle("Page 1", displayMode: .inline)
            .hamburgerButton()
        }
        .menuItem {
            MenuItemView(systemImage: "person", title: "Page 1")
        }
        .tabBarItem {
            TabItemView(systemImage: "person", title: "Page 1")
        }
        .withTag(0)
    }
}
like image 155
Michał Ziobro Avatar answered Sep 15 '25 21:09

Michał Ziobro