One of the most popular ways to create an app with different multiple areas of content is to have tabs. In iOS, the most common is a bottom tab; one click of each tab icon will show a different screen. For example, take the Instagram iOS app, which has Home, Search, Video, Notifications, and Profile tabs. Clicking any of them will take you to a different screen.
In this post, you’ll learn about TabView, with which you can easily create tabs. You’ll create a simple SwiftUI project with a tab. And you’ll also integrate different screens into the project.
What Is TabView in SwiftUI?
TabView, a feature available in the latest SwiftUI, lets you easily create a tab bar in an iOS app. Now, SwiftUI is the new way to create an iOS app that Apple is pushing developers to adopt. It differs from the earlier UIKit-based Storyboard apps in that here, easy-to-use Views help you develop apps more quickly with widgets.SwiftUI resembles Flutter, which has customized widgets to create everything.
The Project Setup
We need to first create a new project by opening Xcode and clicking on New>Project:
A pop-up opens, where you can click on App and then the Next button:
In the next pop-up, give any suitable name as the Product Name. In our case, we’ll use TabView. Select SwiftUI as the interface and make sure to check Include Tests because you’re going to test your app later.
In the next pop-up, just click on the Create button.
Notice that the structure and files are different from those of a Storyboard project. Also, SwiftUI displays an iPhone screen for each file. It will immediately reflect code changes so you don't need to re-run the simulator every time you add code.
Creating a Tab Bar
To create a Tab Bar with TabView, you’ll create a new SwiftUI View file in the root directory.
In the next tab, name the file MyTabBar. Make sure that the Target matches the product name TabView.
You’ll use the newly released icons called SF Symbols in your project. So head over to the official Apple SF Symbols page and download them.
Once you install it on your Mac, you’ll see all the symbols available. You just need to know the name of the symbol you want to use, but you don't need to install it in Xcode.
Now, in the MyTabBar.swift file, we use enum and list all icons as cases, using names taken from the SF Symbols library. Inside the struct MyTabBar, we first bind the Tab to the selected tab variable. After that, we have a fillImage value, in which add .fill to the selected tab.
All the SF Symbols have their corresponding fill image, like for example, the house.fill symbol, which is filled. Next, we loop through the enum and in each iteration show a space, then use an image to show the symbol, and then another space. Also, note that we show the filled image for the selected tab.
Next, we give some additional styles with frame, background, and cornerRadius. You’ll see the result in the iPhone image instantly.
Next, let's add some more animation effects to our selected symbols. First, we scale them if selected, then change their color to red and increase the font size. We’ll also give the selected tab smooth animation.
Display Tab Bar in App
You’ve created the tab bar, but to display it in the app you need to add it in the ContentView.swift file. Here, in the ContentView you first show house as the selected tab. And after that, you’ll show the MyTabBar component with the selected tab. The user can click on whichever tab they want to show.
Next, add an init code in the ContentView.swift file. At first, you need to make it hidden. Then, inside the body, create a ZStack, which will contain two VStacks. The first one will show an image and text corresponding to the selected tab.
The second VStack shows your tab bar. To learn more about ZStack, VStack, and HStack (which you used in the code above), refer to this post. The iPhone image now shows your app perfectly and clicking the tab works properly.
But you should always check your app in iPhone simulator after a milestone. If you start one, you’ll see that everything works correctly.
Separate Screen for Each Tab
In a real app, when we press a tab icon a different screen should appear. Let’s update our app to do the same. Again, create a new SwiftUI View file.
Name it FirstScreen and make TabView the Target.
In the FirstScreen.swift file, add the code below, which will show large text with a pink background color.
Next, create another SwiftUI View file called SecondScreen.swift. This file is similar to the earlier file, except it has a different title and color for the background.
Create another SwiftUI View file called ThirdScreen.swift. This file is also almost similar to an earlier file, but the text is different. Also, you’ll show a nice linear gradient for the background color.
Next, make a file called FourthScreen.swift, which is similar to SecondScreen.swift, except for a different title and different background color.
Lastly, make a file called FifthScreen.swift, which resembles an earlier file, except again, it has a different title and different color background.
To show your five different screens, you need to update your ContentView.swift file. In the TabView for the selected tab, you want to list the five screens. Also, notice the tag function on each screen. It needs to have the correct identifier for each tab.
On running the app in simulator, everything works well.
Testing the App
You can test the app with XCTest, and take the initial steps from our post on XCUI methods.
For testing, you need a unique ID for each element. You can find the IDs with the Accessibility Inspector. To open it, click on Xcode > Open Developer Tool > Accessibility Inspector.
Keep the iOS simulator running on the side. Use the pointer from the Accessibility Inspector to click on different elements. Here, we clicked on the text of the First Screen. And the Label, or unique ID, for this element is First Screen.
Now, create a file called TabViewTests.swift inside the Tests folder. In the file, create a checkLabel function, which will use XCTAssert to check if the label exists.
In the BasicTests.swift file, call the TabViewTests class and then the checkLabel function. After that, click on the play test button next to the function.
The tests will take 10-20 seconds to run and once completed, you’ll see the green ticks checked. It will also show the result in a log.
What We've Covered About TabView in SwiftUI
In this post, we talked about TabView in SwiftUI. Using the easy-to-use code of SwiftUI, we created a fully working tab bar. We also wrote simple test cases using XCTest.
However, test cases emulating each press of a tab and showing the corresponding screen will be very complicated. To make your testing less complicated, try Waldo. You need only provide an APK or IPA file, and then just interact with your app. Waldo automatically generates test cases and emails you the results.
Automated E2E tests for your mobile app
Get true E2E testing in minutes, not months.