After you’ve built a basic view hierarchy, your next step is to control the visual elements and respond to user input. In an iOS app, you use a view controller ( UIViewController ) to manage a content view with its hierarchy of subviews.
A view controller isn’t part of the view hierarchy and it’s not an element in your interface. Instead, it manages the view objects in the hierarchy and provides them with behavior. Each content view hierarchy that you build in your storyboard needs a corresponding view controller, responsible for managing the interface elements and performing tasks in response to user interaction. This usually means writing a custom UIViewController subclass for each content view hierarchy. If your app has multiple content views, you use a different custom view controller class for each content view.
View controllers play many roles. They coordinate the flow of information between the app’s data model and the views that display that data, manage the life cycle of their content views, and handle orientation changes when the device is rotated. But perhaps their most obvious role is to respond to user input.
You also use view controllers to implement transitions from one type of content to another. Because iOS apps have a limited amount of space in which to display content, view controllers provide the infrastructure needed to remove the views of one view controller and replace them with the views of another.
To define interaction in your app, make your view controller files communicate with the views in your storyboard. You do this by defining connections between the storyboard and source code files through actions and outlets.
An action is a piece of code that’s linked to some kind of event that can occur in your app. When that event takes place, the code gets executed. You can define an action to accomplish anything from manipulating a piece of data to updating the user interface. You use actions to drive the flow of your app in response to user or system events.
You define an action by creating and implementing a method with an IBAction return type and a sender parameter.
- – ( IBAction ) restoreDefaults: ( id ) sender ;
The sender parameter points to the object that was responsible for triggering the action. The IBAction return type is a special keyword; it’s like the void keyword, but it indicates that the method is an action that you can connect to from your storyboard in Interface Builder (which is why the keyword has the IB prefix). You’ll learn more about how to link an IBAction action to an element in your storyboard in Tutorial: Storyboards .
Outlets provide a way to reference objects from your interface—the objects you added to your storyboard—from source code files. You create an outlet by Control-dragging from a particular object in your storyboard to a view controller file. This creates a property for the object in your view controller file, which lets you access and manipulate that object from code at runtime. For example, in the second tutorial, you’ll create an outlet for the text field in your ToDoList app to be able to access the text field’s contents in code.
Outlets are defined as IBOutlet properties.
- @property ( weak. nonatomic ) IBOutlet UITextField * textField ;
The IBOutlet keyword tells Xcode that you can connect to this property from Interface Builder. You’ll learn more about how to connect an outlet from a storyboard to source code in Tutorial: Storyboards .
A control is a user interface object such as a button, slider, or switch that users manipulate to interact with content, provide input, navigate within an app, and perform other actions that you define. Controls provide a way for your code to receive messages from the user interface.
When a user interacts with a control, a control event is created. A control event represents various physical gestures that users can make on controls, such as lifting a finger from a control, dragging a finger onto a control, and touching down within a text field.
There are three general categories of event types:
Touch and drag events. Touch and drag events occur when a user interacts with a control with a touch or drag. There are several available touch event stages. When a user initially touches a finger on a button, for example, the Touch Down Inside event is triggered; if the user drags out of the button, the respective drag events are triggered. Touch Up Inside is sent when the user lifts a finger off the button while still within the bounds of the button’s edges. If the user has dragged a finger outside the button before lifting the finger, effectively canceling the touch, the Touch Up Outside event is triggered.
Editing events. Editing events occur when a user edits a text field.
Value-changed events. Value-changed events occur when a user manipulates a control, causing it to emit a series of different values.
As you define the interactions, know the action that’s associated with every control in your app and then make that control’s purpose obvious to users in your interface.
If your app has more than one content view hierarchy, you need to be able to transition between them. For this, you’ll use a specialized type of view controller: a navigation controller ( UINavigationController ). A navigation controller manages transitions backward and forward through a series of view controllers, such as when a user navigates through email accounts, inbox messages, and individual emails in the iOS Mail app.
The set of view controllers managed by a particular navigation controller is called its navigation stack. The navigation stack is a last-in, first-out collection of custom view controller objects. The first item added to the stack becomes the root view controller and is never popped off the stack. Other view controllers can be pushed on or popped off the navigation stack.
Although a navigation controller’s primary job is to manage the presentation of your content view controllers, it’s also responsible for presenting custom views of its own. Specifically, it presents a navigation bar—the view at the top of the screen that provides context about the user’s place in the navigation hierarchy—which contains a back button and other buttons you can customize. Every view controller that’s added to the navigation stack presents this navigation bar. You are responsible for configuring the navigation bar.
You generally don’t have to do any work to pop a view controller off of the navigation stack; the back button provided by the navigation controller handles this for you. However, you do have to manually push a view controller onto the stack. You can do this using storyboards.
Use Storyboards to Define Navigation
So far, you’ve learned about using storyboards to create a single screen of content in your app. Now, you’ll learn about using them to define the flow between multiple scenes in your app.
In the first tutorial, the storyboard you worked with had one scene. In most apps, a storyboard is composed of a sequence of scenes, each of which represents a view controller and its view hierarchy. Scenes are connected by segues. which represent a transition between two view controllers: the source and the destination.
There are several types of segues you can create:
Push. A push segue adds the destination view controller to the navigation stack. Push segues may only be used when the source view controller is connected to a navigation controller.
Modal. A modal segue is simply one view controller presenting another controller modally, requiring a user to perform some operation on the presented controller before returning to the main flow of the app. A modal view controller isn’t added to a navigation stack; instead, it’s generally considered to be a child of the presenting view controller. The presenting view controller is responsible for dismissing the modal view controller it created and presented.
Custom. You can define your own custom transition by subclassing UIStoryboardSegue .
Unwind. An unwind segue moves backward through one or more segues to return the user to an existing instance of a view controller. You use unwind segues to implement reverse navigation.
Instead of segues, scenes may also be connected by a relationship. For example, there’s a relationship between the navigation controller and its root view controller. In this case, the relationship represents the containment of the root view controller by the navigation controller.
When you use a storyboard to plan the user interface for your app, it’s important to make sure that one of the view controllers is marked as being the initial view controller. At runtime, this is the view controller whose content view will be displayed the first time the app is launched and from which you can transition to other view controllers’ content views as necessary.
Now that you’ve learned the basics of working with views and view controllers in storyboards, it’s time to incorporate this knowledge into your ToDoList app in the next tutorial.