Creating Tabbed Applications

Using UITabBarController with Xamarin.iOS

PDF for offline use:
Sample Code:
Related SDKs:

Let us know how you feel about this.


0/250
Thanks for the feedback!

iOS applications using a tab-navigation UI are built using the UITabBarController class. In this article we’ll walk through how to set up a tabbed application that contains several controllers and views. We’ll then examine how to load a UITabBarController when it is not the root controller, such as after a login screen.

Overview

Tabbed applications are used in iOS to support user interfaces where multiple screens can be accessed in no particular order. Through the UITabBarController class, applications can easily include support for such multi-screen scenarios. UITabBarController takes care of the multi-screen management, allowing the application developer to focus on the details of each screen.

Usually, tabbed applications are built with the UITabBarController being the RootViewController of the main window. However, with a bit of additional code, tabbed applications can also be used in succession to some other initial screen, such as the scenario where an application first presents a login screen, followed by the tabbed interface.

We’ll examine using tabs here by working through a walkthrough of a simple application. Then, we’ll look at how to work with tabs in the non- RootViewController scenario.

Introducing UITabBarController

The UITabBarController supports tabbed application development by the following:

  • Allowing multiple controllers to be added to it.
  • Providing a tabbed user interface, via the UITabBar class, to allow a user to switch between controllers and their views.

Controllers are added to the UITabBarController via its ViewControllers property, which is a UIViewController array. The UITabBarController itself handles loading the proper controller and presenting its view based upon the selected tab.

The tabs are instances of the UITabBarItem class, which are contained in a UITabBar instance. Each UITabBar instance is accessible through the TabBarItem property of the controller in each tab.

To get an understanding of how to work with the UITabBarController, let’s walk through building a simple application that uses one.

Tabbed Application Walkthrough

For this walkthrough we’re going to create the following application:

Although there is already a tabbed application template available in Xamarin Studio, for this example, we’re going to work from an empty project to gain a better understanding of how the application is constructed.

Creating the Application

Let’s start by creating a new application.

Select the File > New > Solution menu item in Xamarin Studio and select a iOS > App > Empty Project template, Name the project TabbedApplication, as shown below:

Adding the UITabBarController

Next, add an empty class by selecting File > New File and choosing the General : Empty Class template. Name the file TabController as shown below:

The TabController class will contain the implementation of the UITabBarController that will manage an array of UIViewControllers. When the user selects a tab, the UITabBarController will take care of presenting the view for the appropriate view controller.

To implement the UITabBarController we need to do the following:

  1. Set the base class of TabController to UITabBarController .
  2. Create UIViewController instances to add to the TabController .
  3. Add the UIViewController instances to an array assigned to the ViewControllers property of the TabController .

Add the following code to the TabController class to achieve these steps:

using System;
using UIKit;

namespace TabbedApplication {
        public class TabController : UITabBarController {

                UIViewController tab1, tab2, tab3;

                public TabController ()
                {
                        tab1 = new UIViewController();
                        tab1.Title = "Green";
                        tab1.View.BackgroundColor = UIColor.Green;

                        tab2 = new UIViewController();
                        tab2.Title = "Orange";
                        tab2.View.BackgroundColor = UIColor.Orange;

                        tab3 = new UIViewController();
                        tab3.Title = "Red";
                        tab3.View.BackgroundColor = UIColor.Red;

                        var tabs = new UIViewController[] {
                                tab1, tab2, tab3
                        };

                        ViewControllers = tabs;
                }
        }
}

Notice that for each UIViewController instance, we set the Title property of the UIViewController. When the controllers are added to the UITabBarController, the UITabBarController will read the Title for each controller and display it on the associated tab’s label as shown below:

Setting the TabController as the RootViewController

The order that the controllers are placed in the tabs corresponds to the order they are added to the ViewControllers array.

To get the UITabController to load as the first screen, we need to make it the window’s RootViewController, as shown in the following code for the AppDelegate:

[Register ("AppDelegate")]
        public partial class AppDelegate : UIApplicationDelegate
        {
                UIWindow window;
                TabController tabController;

                public override bool FinishedLaunching (UIApplication app, NSDictionary options)
                {
                        window = new UIWindow (UIScreen.MainScreen.Bounds);

                        var tabController = new TabController ();
                        window.RootViewController = tabController;

                        window.MakeKeyAndVisible ();

                        return true;
                }
        }

If we run the application now, the UITabBarController will load with the first tab selected by default. Selecting any of the other tabs results in the associated controller’s view being presented by the UITabBarController, as shown below where the end user has selected the second tab:

Modifying TabBarItems

Now that we have a running tab application, let’s modify the TabBarItem to change the image and text that is displayed, as well as to add a badge to one of the tabs.

Setting a System Item

First, let’s set the first tab to use a system item. In the constructor of the TabController, remove the line that sets the controller’s Title for the tab1 instance and replace it with the following code to set the controller’s TabBarItem property:

tab1.TabBarItem = new UITabBarItem (UITabBarSystemItem.Favorites, 0);

When creating the UITabBarItem using a UITabBarSystemItem, the title and image are provided automatically by iOS, as seen in the screenshot below showing the F avorite s icon and title on the first tab:

Setting the Title and Image

In addition to using a system item, the title and image of a UITabBarItem can be set to custom values. For example, change the code that sets the TabBarItem property of the controller named tab2 as follows:

tab2 = new UIViewController ();
tab2.TabBarItem = new UITabBarItem ();
tab2.TabBarItem.Image = UIImage.FromFile ("second.png");
tab2.TabBarItem.Title = "Second";
tab2.View.BackgroundColor = UIColor.Orange;

The above code assumes an image named second.png has been added to the root of the project in Xamarin Studio. We have actually added three images to our project, to cover all device resolutions, as shown below:

The tab image should be a 30x30 png with transparency for normal resolution, 60x60 for high resolution and 90 x 90 for iPhone 6 Plus resolution. In our code, we only need to load the file named second.png and iOS will automatically load the high resolution one on devices with a Retina display. You can read more about this in the Working with Images guides. By default tab bar items are grey, with a blue tint when selected.

Note

The images above could also be added to the Resources directory, which is a special directory whose content will automatically be copied to the root of the application bundle:

Additionally, when we set the Title property directly on the TabBarItem, it would override any value set for Title on the controller itself.

When we run the application now, the second tab shows our custom title and image as shown below:

Setting the Badge Value

A tab can also display a badge. For example, add the following line of code to set a badge on the third tab:

tab3.TabBarItem.BadgeValue = "Hi";

Running this results in a red label with the string "Hi” in the upper left corner of the tab as shown below:

The badge is often used to display a number indication unread, new items. To remove the badge, set the BadgeValue to null as shown below:

tab3.TabBarItem.BadgeValue = null;

Tabs in Non-RootViewController Scenarios

In the example above, we showed how to work with a UITabBarController when it is the RootViewController of the window. In this example we will examine how to use a UITabBarController when it is not the RootViewController and show how this is created use Storyboards.

Initial Screen Example

For this scenario, the initial screen loads from a controller that is not a UITabBarController. When the user interacts with the screen by tapping a button, the same View Controller will be loaded into a UITabBarController, which is then presented to the user. The following screenshot shows the application flow:

Let’s start a new application for this example. Again, we’ll use the iPhone > App > Empty Project (C#) template, this time naming the project InitialScreenDemo.

In this example We’ll need a Storyboard to hold our View Controllers. To add a Storyboard:

  • Right-click on the Project name, and select Add > New File.

  • When the New File dialog appears, navigate to iOS > Empty iPhone Storyboard.

Let's call this new Storyboard MainStoryboard , as illustrated below:

There are a few important steps to note when adding a Storyboard to a previously non-storyboard file, which are covered in the Introduction to Storyboards guide. These are:

  • Add your Storyboard name to the Main Interface section of the Info.plist.
  • In your App Delegate, override the Window method, with the following code:
    public override UIWindow Window {
          get;
          set;
        }

We are going to need three View Controllers for this example. One, named ViewController1, will be used as our Initial View Controller and in the first tab. The other two, named ViewController2 and ViewController3, which will be used in the second and third tabs respectively.

Open the Designer by double clicking the MainStoryboard.storyboard file, and drag three View Controllers on to the design surface. We want each of these View Controllers to have their own class corresponding to the name above, So, under Identity > Class, type in its name, as illustrated in the screenshot below:

Xamarin Studio will automatically generate the classes and designer files needed, this can be seen in the Solution Pad, as illustrated below:

Creating the UI

Next, we’ll create a simple user interface for each of the ViewController's views, using the Xamarin iOS Designer.

We want to drag a Label and a Button onto ViewController1 from the ToolBox on the right hand side. Next we'll use the Properties Pad to edit the name and text of the controls to the following:

  • Label : Text = One
  • Button : Title = User Takes Some Initial Action

We will be controlling the visibility of our button in a TouchUpInside event, and we need to refer to it in the code behind. Let's identify it with the Name aButton in the Properties Pad, as depicted in the following screenshot:

Your Design Surface should now look similar to the screenshot below:

Let's add a little more detail to ViewController2 and ViewController3, by adding a label to each, and changing the text to 'Two' and 'Three' respectively. This highlights to the user which tab/View we are looking at.

Wiring Up the Button

We’re going to load ViewController1 when the application first starts. When the user taps the button, we’ll hide the button and load a UITabBarController with the ViewController1 instance in the first tab.

When the user releases the aButton, we want a TouchUpInside event to be triggered. Let's select the button, and in the Events Tab of the Properties pad, declare the event handler – InitialActionCompleted – so it can be referred to in code. This is illustrated in the screenshot below:

We now need to tell the View Controller to hide the button when the event fires InitialActionCompleted. In ViewController1, add the following partial method:

partial void InitialActionCompleted (UIButton sender)
    {
      aButton.Hidden = true;  
    }

Save the file, and run the application. We should see screen one appear and the button disappear on Touch Up.

Adding the Tab Bar Controller

We now have our Initial view working as expected. Next, we want to add it to a UITabBarController, along with Views 2 and 3. Let's open the Storyboard in the Designer.

In the Toolbox, search for the Tab Bar Controller under Controllers & Objects and drag this onto the Design Surface. As you can see in the screenshot below, the Tab Bar Controller is UI-less and therefore brings two View Controllers with it by default:

Delete these new View controllers by selecting the black bar at the bottom and pressing delete.

In our Storyboard, we can use Segues to handle the transitions between the TabBarController and our View Controllers. After interacting with the Initial View, we want to load it into the TabBarController presented to the user. Let's set this up in the designer.

Ctrl-Click and Drag from the button to the TabBarController. On mouse-up, a context menu will appear. We want to use a modal segue.

To set up each of our tabs, Ctrl-Click from the TabBarController to each of our View Controllers in order from one to three, and select the Relationship Tab from the context menu, as illustrated below:

Your Storyboard should resemble the screenshot below:

If we click on one of the tab bar items and explore the properties panel, you can see a number of different options, as illustrated below:

We can use this to edit certain attributes such as the badge, the title and the iOS identifier, among others

If we save and run the application now, we'll find that the button reappears when the ViewController1 instance is loaded into the TabBarController. Let's fix this by checking to see if the current View has a parent View Controller. If it does, we know we are inside the TabBarController, and therefore the button should be hidden. Let's add the code below to the ViewController1 class:

public override void ViewDidLoad ()
{
     if (ParentViewController != null){
       aButton.Hidden = true;
     }

}

When the application runs and the user taps the button on the first screen, the UITabBarController is loaded, with the view from the first screen placed in the first tab as shown below:

Save the files and run the application:

Summary

This article covered how to use a UITabBarController in an application. We walked through how to load controllers into each tab as well as how to set properties on tabs such the title, image and badge. We then examined, using storyboards, how to load a UITabBarController at runtime when it is not the RootViewController of the window.

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.