Note 19-mar-2020: In the meantime, I went much deeper into the question how a scrollable tab view with animations can be realized using pure SwiftUI. I came up with a solution that is published on GitHub.
Please also note that there is a follow-up article on this one.
SwiftUI provides a
TabView. However, checking for the currently selected tab, and reordering of the tabs lead to problems if you want, as an example, save and restore the new sort order on app restart.
So, I tried to design a TabBar which can be used pretty conveniently as replacement for the original
Wrapping the UITabBarController
First, we’re wrapping the
UITabBarController into a
UIViewControllerRepresentable. The procedure is explained in various tutorials across the web, so I’ll focus on some additional aspects here.
- This is the index that we want to have maintained by the
- Similarily, this is the order in which the tabs shall appear.
- We set the
Coordinatoras delegate for the
UITabBarController. This allows us to react on the events.
- From the given list of
IRTabBarItems, we create the list of view controllers, as well as the attached
UITabBarItems, that we need for the
- If we have a
tabOrderavailable, we sort those list of view controllers accordingly.
- We finish the setup of the
Reacting on events
Next, we need the
Coordinator. Its job is simply to react on the events we’ll notice.
- We save the parent
structjust for convenience. This avoids some castings lateron.
- We take the
selectedIndexand save it to the parent’s
- The same is true for the new sort order.
Defining the tab bar item
Now, let’s define an
IRTabBarItem , so that we can provide title, image and target views to the tab bar.
Using the new view
We can now use the view like any other SwiftUI view:
- We use a model to provide all we need for the view. We’ll see that in a moment.
- That’s our new
IRTabBarwith the items provided by the model, and the selected index and the tab order bound to the model’s properties.
The model provides the convenience
Finally, we have to implement the model that the view observes.
- Those two are custom property wrappers that read and write values from/to the user defaults.
- These are the observed properties; if set, the user defaults are updated as well. (I’m sure this can be done nicer…)
- The preset for the tab bar items we want to present. Derived from an enumeration which provides
title, systemImageName, viewfor each case.
- This reads the saved settings and sets the published properties accordingly.
With this view, your have a pretty easy way to add a reactive
TabView to your app. If you need additional features, such as transitioning animations, you can easily add them to the
Coordinator. Or, you can even publish the items and set them dynamically in. the model, e.g., if you want to show or hide tabs depending on other conditions.