You would like to give your users the option to switch from one section of your app to another, with ease.
If you use your iPhone as an alarm clock, you have certainly seen a tab bar. Have a look at Figure 1-38. The bottom icons labeled World Clock, Alarm, Stopwatch, and Timer are parts of a tab bar. The whole black bar at the bottom of the screen is a tab bar, and the aforementioned icons are tab bar items.
A tab bar is a container controller. In other words, we
create instances of UITabBarController
and add them to the window
of our application. For each tab bar item, we add a navigation
controller or a view controller to the tab bar, and those items will
appear as tab bar items. A tab bar controller contains a tab bar of type UITabBar
. We don’t create this object
manually. We create the tab bar controller, and that will create the tab
bar object for us. To make things simple, remember that we instantiate a
tab bar controller and set the view controllers of that tab bar to
instances of either UIViewController
or UINavigationController
if we
intend to have navigation controllers for each of the tab bar items
(aka, the view controllers set for the tab bar controller). Navigation
controllers are of type UINavigationController
that are subclasses of
UIViewController
. Therefore, a
navigation controller is a view controller, but view controllers of type
UIViewController
are not navigation
controllers.
So let’s assume we have two view controllers with class names
FirstViewController
and SecondViewController
.
-
(
BOOL
)
application:
(
UIApplication
*
)
application
didFinishLaunchingWithOptions:
(
NSDictionary
*
)
launchOptions
{
self
.
window
=
[[
UIWindow
alloc
]
initWithFrame
:
[[
UIScreen
mainScreen
]
bounds
]];
[
self
.
window
makeKeyAndVisible
];
FirstViewController
*
firstViewController
=
[[
FirstViewController
alloc
]
initWithNibName:
nil
bundle:
NULL
];
SecondViewController
*
secondViewController
=
[[
SecondViewController
alloc
]
initWithNibName:
nil
bundle:
NULL
];
UITabBarController
*
tabBarController
=
[[
UITabBarController
alloc
]
init
];
[
tabBarController
setViewControllers
:
@
[
firstViewController
,
secondViewController
]];
self
.
window
.
rootViewController
=
tabBarController
;
return
YES
;
}
A tab bar, when displayed on the screen, will display tab bar items just like those we saw in Figure 1-38. The name of each of these tab bar items comes from the title of the view controller that is representing that tab bar item, so let’s go ahead and set the title for both of our view controllers.
Warning
When a tab bar loads up, it loads only the view of the first
view controller in its items. All other view controllers will be
initialized, but their views won’t be loaded. This means that any code
that you have written in the viewDidLoad
of the second view controller
will not get executed until after the user taps
on the second tab bar item for the first time. So if you assign a
title to the second view controller in its viewDidLoad
and run your app, you will find
that the title in the tab bar item is still empty.
For the first view controller, we choose the title
First
:
#import "FirstViewController.h"
@implementation
FirstViewController
-
(
id
)
initWithNibName:
(
NSString
*
)
nibNameOrNil
bundle:
(
NSBundle
*
)
nibBundleOrNil
{
self
=
[
super
initWithNibName
:
nibNameOrNil
bundle:
nibBundleOrNil
];
if
(
self
!=
nil
)
{
self
.
title
=
@"First"
;
}
return
self
;
}
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
];
self
.
view
.
backgroundColor
=
[
UIColor
whiteColor
];
}
And for the second view controller, we pick the title
Second
:
#import "SecondViewController.h"
@implementation
SecondViewController
-
(
id
)
initWithNibName:
(
NSString
*
)
nibNameOrNil
bundle:
(
NSBundle
*
)
nibBundleOrNil
{
self
=
[
super
initWithNibName
:
nibNameOrNil
bundle:
nibBundleOrNil
];
if
(
self
!=
nil
)
{
self
.
title
=
@"Second"
;
}
return
self
;
}
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
];
self
.
view
.
backgroundColor
=
[
UIColor
whiteColor
];
}
Now let’s run our app and see what happens (Figure 1-42).
You can see that our view controllers do not
have a navigation bar. What should we do? It’s easy. Remember that a
UINavigationController
is actually a
subclass of UIViewController
. So we
can add instances of navigation controllers to a tab bar, and inside
each navigation controller, we can load a view controller. What are we
waiting for, then?
-
(
BOOL
)
application:
(
UIApplication
*
)
application
didFinishLaunchingWithOptions:
(
NSDictionary
*
)
launchOptions
{
// Override point for customization after application launch.
self
.
window
=
[[
UIWindow
alloc
]
initWithFrame
:
[[
UIScreen
mainScreen
]
bounds
]];
[
self
.
window
makeKeyAndVisible
];
FirstViewController
*
firstViewController
=
[[
FirstViewController
alloc
]
initWithNibName:
nil
bundle:
NULL
];
UINavigationController
*
firstNavigationController
=
[[
UINavigationController
alloc
]
initWithRootViewController:
firstViewController
];
SecondViewController
*
secondViewController
=
[[
SecondViewController
alloc
]
initWithNibName:
nil
bundle:
NULL
];
UINavigationController
*
secondNavigationController
=
[[
UINavigationController
alloc
]
initWithRootViewController:
secondViewController
];
UITabBarController
*
tabBarController
=
[[
UITabBarController
alloc
]
init
];
[
tabBarController
setViewControllers
:
@
[
firstNavigationController
,
secondNavigationController
]];
self
.
window
.
rootViewController
=
tabBarController
;
return
YES
;
}
And the results? Exactly what we wanted (Figure 1-43).
As we can see in Figure 1-38, each tab bar item
can have text and an image. We’ve learned that, using the title
property of a view controller, we can
specify this text, but what about the image? It turns out that every view controller has a property called
tabItem
. This property is the tab
item for the current view controller, and you can use this property to
set the image of the tab bar item through the image
property of the tab item. I’ve already
designed two images, a rectangle and a circle. I’m going to display them
as the tab bar item image for each of my view controllers. Here is code
for the first view controller:
-
(
id
)
initWithNibName:
(
NSString
*
)
nibNameOrNil
bundle:
(
NSBundle
*
)
nibBundleOrNil
{
self
=
[
super
initWithNibName
:
nibNameOrNil
bundle:
nibBundleOrNil
];
if
(
self
!=
nil
)
{
self
.
title
=
@"First"
;
self
.
tabBarItem
.
image
=
[
UIImage
imageNamed
:
@"FirstTab"
];
}
return
self
;
}
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
];
self
.
view
.
backgroundColor
=
[
UIColor
whiteColor
];
}
And here it is for the second view controller:
-
(
id
)
initWithNibName:
(
NSString
*
)
nibNameOrNil
bundle:
(
NSBundle
*
)
nibBundleOrNil
{
self
=
[
super
initWithNibName
:
nibNameOrNil
bundle:
nibBundleOrNil
];
if
(
self
!=
nil
)
{
self
.
title
=
@"Second"
;
self
.
tabBarItem
.
image
=
[
UIImage
imageNamed
:
@"SecondTab"
];
}
return
self
;
}
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
];
self
.
view
.
backgroundColor
=
[
UIColor
whiteColor
];
}
Running the app in the simulator, we will see that the images are displayed properly (Figure 1-44).
Get iOS 7 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.