In this tutorial we’ll discuss and implement iOS UI Navigation Controller. It’s another common UI element that’s used as the base for many iOS apps.
A Navigation Controller also holds a UIView class instance. The primary use of a navigation controller is to create and hold a hierarchy of view controllers in a stack(officially termed as navigation stack). In others words the Navigation Controller maintains a history of View Controllers the user has browsed through. A Navigation Controllers view consists of many subviews that include a navigation bar at the top ( which contains the optional title, back button and other bar buttons), a custom content view and an optional toolbar at the bottom.
To setup a navigation controller, select the initial view controller in your storyboard and go to Editor>Embed In>Navigation Controller. The storyboard would look like this:
We’ll need to add View Controllers to the storyboard to bring the Navigation Controller in use. Before we do that we’ll discuss segues that are an important component for moving across View Controllers.
Segues
Segues provide a mechanism to connect two View Controllers/scenes. There are many kinds of segues.
- Show/Push : This pushes the next View Controller onto the navigation stack thereby allowing the user to click the back button to return to the previous screen through the back button on the top left of the Navigation Bar.
- Show Detail : The next view controller content is present in the details area if it’s a master detail screen (UISplitViewController). Else if it’s not the master detail type then the current content is replaced with the new one.
- Present Modally : This animates the next transition on the screen in a presentation style that is chosen from the list of styles present( or a custom one). Typically the next views transitions into the screen from bottom to upwards. In cases of iPad it centers itself in the middle of the screen with the previous view controller content in background.
- Popover presentation : On an iPad, this shows the new View Controller over the previous one in a smaller box, usually with an arrow pointing to which UI Element created the popover. When used on an iPhone, it is not much different than the Present Modally segue by default, but can be configured to act more like an iPad one.
- Custom : We can define our own behaviour for this type of segue.
The Segue object belongs to the class UIStoryboardSegue.
To pass data from one ViewController to another, we’ll have to override prepareForSegue
function.
The show/push type of segue has a default back button in the navigation bar of the Child View Controller.
For the other type of segues we need to add an Unwind Segue method (more on this in later tutorials). The unwind segue method is created by adding an IBAction button with parameters as UIStoryboardSegue in the Parent View controller.
In this application we’ll add a Second View Controller that comes up from the first View Controller using segues. We’ll add a UITextField where the user enters the value that’s passed and displayed in the next view controller.
Control+ click and drag the button to the Second View Controller. Chose push as the manual type of segue.
The screen should look like the one given below.
Notice the segue symbol between the two View Controllers. The symbol is different for different type of segues.
Focus the segue symbol and name the segue identifier as “mySegue”.
Add a new Cocoa class file for the Second View controller (it should be a subclass of UIViewController. We’ve named it here as SecondScreen.swift
. Select the Second View Controller and link the class name in the Identity Inspector as shown in the image below.
Project Structure
The SecondScreen.swift
file is for the Second View Controller.
The info.plist
file is a list of properties and it provides another method for storing information for our app.
Code
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import UIKit class ViewController: UIViewController,UITextFieldDelegate { @IBOutlet var textToPass: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. textToPass.delegate=self } override func viewWillAppear(animated: Bool) { self.navigationItem.title = "First Screen" } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { self.navigationItem.title = nil if segue.identifier == "mySegue"{ let s = segue.destinationViewController as! SecondScreen s.studentName = self.textToPass.text } } func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. { textField.resignFirstResponder() return true; } override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { textToPass.resignFirstResponder() self.view.endEditing(true) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
In the above code we’ve added the UITextFieldDelegate Protocol for handling the UITextField methods.
We’ve handled the UITextField such that the keyboard should be dismissed if tapped outside or return key is pressed. Notice the difference in the code from the one we wrote for Objective-C.
1 |
@IBOutlet var textToPass: UITextField! |
The ! mark means that the var value is strictly of type UITextField and it cannot be null.
1 |
textToPass.delegate=self |
The above statement programmatically assigns the delegate of the UITextField to the view controller itself. It’s similar to Control+dragging the textfield to the dock in the storyboard.
The prepareForSegue is the most important method in this class. Let’s look into it.
1 2 3 4 5 6 7 8 |
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { self.navigationItem.title = nil if segue.identifier == "mySegue"{ let s = segue.destinationViewController as! SecondScreen s.pass = self.textToPass.text } } |
The next screen shows a back button by default only when the previous screen doesn’t contain a title. Else the back text of the next screen would be replaced with the title of this screen.
Hence we’ve assigned the title to null. The segue identifier string should be the same as the one declared in the storyboard.
1 |
s.studentName = self.textToPass.text |
The pass
string is an instance variable of the SecondScreen.swift. What we’ve done here is assign the instance variable of the SecondScreen.swift
class to the text the user types in the textfield here.
SecondScreen.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import UIKit class SecondScreen: UIViewController { var pass:String? @IBOutlet var textReceived: UILabel! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. if let name = pass { if name.characters.count>0 { textReceived.text = name } } } } |
This class just displays the pass
string in the UILabel on the screen only if the user had typed in the UITextField widget, else it shows the default label string.
The output of the application in action is given below.
This brings an end to this tutorial. You can download the iOS NavController project from the link below.