Tab Bar Controller Guide - alberto-campos/ios_guides GitHub Wiki
- Overview
- Using tab bar controllers in storyboards
- Programatically setting up a tab bar controller
- Responding to a tab being selected
- The "More.." button
- Customizing the appearance of the tab bar
Overview
Tab bar controllers are implemented by the
UITabBarController class. They allow a user of to
switch between multiple arbitrary view controllers by maintaining an
array of UIViewControllers
.
They can be used to allow the user to navigate between entirely different parts of your application, or they can be used to display two different views of the same backing data. Tab bar controllers also have the built-in ability to display a "More..." interface when more than 5 tabs are added. They can also let the user customize which tabs are shown by on the main tab bar when there are more than 5 tabs. An example of this behavior is found in the standard iOS "Music" app (previously "iTunes").
This guide covers common use cases for tab bar controllers. A more in depth guide by Apple can be found here
In order to demonstrate basic functionality of the UITabBarController
we will build a very basic clone of the standard iOS "Clock" app. Our
app will have only two tabs one to display the current time, and the
other will implement the stopwatch functionality.
Using tab bar controllers in storyboards
We create a new "Single View Application" and add two subclasses of
UIViewController
via File -> New -> iOS -> Source -> Cocoa Touch Class
. We create a ClockViewController
and a
StopwatchViewController
.
We open up our Main.storyboard
and go ahead and delete the
pregenerated view controller. Dragging a "Tab Bar Controller" from the
Object Library into the storyboard automatically creates two view
controllers that are already in the tab bar controller's array of view
controllers. We also set the the the tab bar controller to be our
application's root view controller selecting it and by ticking the Is Initial View Controller
checkbox.
Adding tabs to the tab bar controller
We can add more tabs by dragging a new view controller frm
the Object Library onto the storyboard and then control-dragging from
the tab bar controller to our the new view controller and then selecting
Relationship Segues -> view controllers
. This will add the new view
controller to the tab bar controller's array of view controllers. It
also automatically adds a tab bar item to our new view controller which
will alow us to configure the appearance of the button that represents
this view controller in the tab bar.
In our case we only needed two view controllers total, but we removed and readded one above to illustrate the technique.
We set the Custom Class
property of one of the view controllers in our
tab bar to ClockViewController
and the other to
StopwatchViewController
. Now we can design our view controllers and
connect @IBOutlets
as we would any other view controller.
We add a single label to the ClockViewController
. It will display the
current time. We add a label to the StopwatchViewController
top
display the elapsed time and add two buttons for "start" and
"stop/reset". We add @IBOutlets
for our two labels and add
@IBActions
to respond to each button being tapped.
Finally we can add the code to make our clock tick
class ClockViewController: UIViewController {
@IBOutlet weak var timeLabel: UILabel!
var timer: NSTimer?
let dateFormatter = NSDateFormatter()
func updateTime() {
timeLabel.text = dateFormatter.stringFromDate(NSDate())
}
override func viewDidLoad() {
dateFormatter.dateFormat = "hh:mm:ss"
updateTime()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
timer?.invalidate()
}
}
import UIKit
class StopwatchViewController: UIViewController {
@IBOutlet weak var elapsedTimeLabel: UILabel!
let dateFormatter = NSDateFormatter()
var elapsedTimeAtStop: NSTimeInterval = 0
var dateAtStart: NSDate?
var timer: NSTimer?
override func viewDidLoad() {
dateFormatter.dateFormat = "mm:ss.S"
dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
updateElapsedTime()
}
func updateElapsedTime() {
elapsedTimeLabel.text = dateFormatter.stringFromDate(dateForFormatter())
}
private func dateForFormatter() -> NSDate {
if let startDate = self.dateAtStart? {
let intervalSinceStart = NSDate().timeIntervalSinceDate(startDate)
let totalElapsedTime = elapsedTimeAtStop + intervalSinceStart
return NSDate(timeIntervalSince1970: totalElapsedTime)
}
return NSDate(timeIntervalSince1970: elapsedTimeAtStop)
}
@IBAction func startButtonTapped(sender: AnyObject) {
if dateAtStart == nil {
dateAtStart = NSDate()
timer = NSTimer.scheduledTimerWithTimeInterval(1.0/10.0, target: self, selector: "updateElapsedTime", userInfo: nil, repeats: true)
}
}
@IBAction func stopButtonTapped(sender: AnyObject) {
if let startDate = dateAtStart? { // stop
elapsedTimeAtStop += NSDate().timeIntervalSinceDate(startDate)
} else { // reset
elapsedTimeAtStop = 0
}
timer?.invalidate()
timer = nil
dateAtStart = nil
updateElapsedTime()
}
}
Programatically setting up a tab bar controller
to be completed
Responding to a tab being selected
to be completed
The "More.." button
to be completed
Configuring what is allowed to be reordered
to be completed
Customizing the appearance of the tab bar
to be completed