24 Sep, 2019

SwiftUI, TabView it is

SwiftUI, TabView it is

I have been following the progress on SwiftUI's TabView class since June. My progress through different Betas can be read here and here. With the stable release of Xcode 11, it is finally time to catch up on the at least for now formalized form of this type of navigation hierarchy so common in App development.

The Basics

Except for the name change from TabbedView to TabView the basic way this works hasn't changed much from the Betas. The main actors in this basic example are: TabView and tabItem. (and of course, the content inside each tab).

TabView

Defined by Apple as:

A view that switches between multiple child views using interactive user interface elements.

How many tabs fit in a TabView ?

It looks like on iPhone, the limit is 5 and on iPad it's 8.

After that you will see a "More ... " tab item that offers a list view to choose from the remaining options.

TabView in tvOS, presents a different behavior with a hard limit of 7 tabs. There is no "More..." tab and any tabs added after the 7th are ignored.

.tabItem(_:)

tabItem is the other major player in a TabView setup.

Defined by Apple as:

Sets the tab item to be used for this content.

TabView content is defined by children views added inside its closure that have the tabItem modifier applied to them.

We can in theory add more children inside TabView's closure but unless we add the tabItem modifier they are not recognized as sub views you can toggle, and they will display some ugly empty space.

Another "quirk" I have noticed playing with tabItem is that it can technically accept any View inside its closure but only the first Image and Text instances are used in the tab's display, and in that order only. That is, even if you specify the Text before the Image the Image then Text display is used. All other View are ignored.

Which really makes me wonder ... If the tabItem instance method only really processes one Image and one Text and only in that order, why not make it have a signature like func tabItem<V>tabItem(Image: Image, Text: Text) -> some View where V : View ?

.tag

Defined by Apple as:

Sets a tag for the view in order to differentiate it from a list of view options.

The tag modifier is not exactly required anymore. It used to be during the Beta's as documented in this stack overflow answer.

Sample project

You can find a finalized sample project at https://github.com/piterwilson/MyTabbedView

Sources and Further reading