Jump to content

Understanding view controllers in Cocoa Touch

0
  TheBarbarianGroup's Photo
Posted Sep 24 2009 10:57 AM

A thorough understanding of the standard interaction design patterns included in UIKit must include view controllers. Cocoa and Cocoa Touch applications tend to follow a classic model-view-controller (MVC) architectural pattern. Domain objects, or models, are separated from the controller code operating on them. Further separated are the user interface views that allow users to interact with controls, input data, and understand data in meaningful ways.

In Cocoa Touch, controllers are most often instances of a view controller.

View controllers, as represented in UIKit by the UIViewController class, manage the views that comprise a given Cocoa Touch user interface. Controller classes mediate the communication between models and views, manage asynchronous operations such as networking and threading, and handle the configuration and logic that make your particular application more than the sum of its logical domain objects. In Cocoa Touch, view controllers take on a subset of the application duties by managing the logic specifically around views, with each view controller typically in charge of a single view.

Figure A, “A single UIViewController and its UIView” shows the relationship for the simplest case: a UIViewController and a UIView.

Figure A. A single UIViewController and its UIView

Attached Image

View Controller Subclasses and Corresponding Application Templates

You may wonder why the UIViewController class is being discussed in the context of choosing an application template. The reason is that each application template corresponds to one of several UIViewController subclasses. Choosing the application template that works best for the current iteration of your application requires a basic understanding of the stock view controller subclasses.

There are three types of view controllers you will encounter when creating new iPhone projects. The first is the simplest: the UIViewController. The next is the UITableViewController. The final view controller subclass is the UITabBarController.

UIViewController and view-based applications

Sometimes the best solution to a problem is a very simple application. For most of us, this is a dream scenario. Xcode supplies an application template that sets up a single view controller and an associated view.

View controller instances, as represented by the UIViewController base class, each have an instance variable called view that points to a UIView or UIView subclass. As mentioned in the previous section, the job of a view controller is to manage all logic for a view, often acting as a delegate for event handling or as a data source.

The view-based application template is a great place to start if your application won’t allow users to navigate across a set of data or across a linear process, such as a wizard. In those cases, a navigation-based application template is a more suitable foundation.

If you’d like to use a view-based application template for your application but would prefer to support an application configuration screen in your application, you should consider the utility application template.

UIViewController and utility applications

The utility application template builds upon the simple view-based application template by generating code and Interface Builder files that let users alternate between your primary view and an alternate view. This structure originated in Mac OS X desktop widgets, and is in use for standard, lightweight applications that ship with the iPhone and iPod Touch, such as the Weather application.

UITabBarController and tab-based applications

Tab-based applications give users a very accessible and understandable mechanism for selecting among two or more sibling view controllers. Think of tab controllers the way you might think of TV channels. You can touch a tab to switch to its controller and view, which together make up the content for that tab. Proper use of tabs is to show separate functional areas of an application as separate but equal tabs. In other words, you don’t want to have a high-level tab, and then a tab next to it that represents a lower-level bit of functionality that might otherwise belong “under” the first. The Tweetie application by Atebits uses a tab bar to display various types of messages on Twitter. For example, there is a tab for your main Twitter feed, one for replies sent to you, one for direct messages, and one for favorites.

Figure B, “Tab bar application” shows the result of compiling the default tab bar application template.

Figure B. Tab bar application

Attached Image

Note the two tabs at the bottom of each screen. Technically, selecting a tab switches the current UIViewController pointed to by the main UITabBarController instance. From a non-technical user perspective, selecting the second tab declares to the application that the user would like to focus on a different area of functionality from that in the first tab.

Each tab bar item in the tab bar represents a single UIViewController or UIViewController subclass. That means you can choose to combine your view controllers, such as using a UINavigationController or UITableViewController “inside” one of your tabs.

Note

One note of advice: retrofitting an application into a tab-based application can be somewhat tedious, though far from the end of the world. Still, if you think you might switch to a tab-based architecture in the near future, it’s worth using the tab bar application template from the beginning of your development.

UINavigationController and navigation-based applications

A navigation controller is a special UIViewController subclass that allows users to build and drill into a stack of UIViewController instances. This is useful when users traverse nodes in a tree or linked list data structure.

Think of the stack of view controllers as a stack of paper. The navigation controller manages the stack and lets users trigger actions that add a new sheet to the top of the stack or that, alternately, remove a sheet from the stack. To programmers, this is called “pushing” and “popping” items onto a stack.

When you tell a navigation controller to push a new view controller and view onto the top of the stack, the navigation controller will automatically load the new controller and view into memory and then trigger an animation that slides the current view offscreen, to the left, while sliding the new view onscreen, from the right. You can see this in the Mail application when selecting a message to read, for example. This mechanism is seen consistently among a large number of Cocoa Touch applications and has, in some ways, become an iconic transition for the platform.

Figure C, “UINavigationController and UIViewController relationships” shows the relationship between a UINavigationController and its subordinate UIViewController instances.

When prototyping your application, try to decide whether you will be navigating down through a hierarchical dataset, such as a list of messages. If so, consider choosing an application template that builds upon a UINavigationController foundation.

Figure C. UINavigationController and UIViewController relationships

Attached Image

UITableViewController and navigation-based applications

Table views are used to manage a list of table cells, with each cell representing a distinct item of some sort. Typically, there is a one-to-one relationship among onscreen table view cells and model objects. For example, the Contacts application that ships with the iPhone maps onscreen cells, or rows, with each user stored in the address book.

When using a UITableViewController in a navigation-based application, the typical pattern is to represent data as a tree with the first level of objects listed in the table. When tapping a single cell, a new view controller is added to the top of the navigation controller stack and its view is transitioned in from right to left. Depending on your data structure, the new view controller might be another UITableViewController representing all child nodes for the selected node, or it might be a custom UIView that shows custom art and layout.

Given the extensibility of UITableViewControllerCell instances, it’s worth exploring the use of table views for many problems.

Figure D, “A series of UITableViewControllers in a UINavigationController stack” shows screenshots of an application that traverses a set of nodes using sequential UITableViewControllers on a UINavigationController stack.

Figure D. A series of UITableViewControllers in a UINavigationController stack

Attached Image

OpenGL ES applications

Applications that are based on the OpenGL ES application template do not use UIViewController subclasses. Instead, the default template uses an EAGLView—a subclass of UIView—to an instance variable in the application delegate class. The EAGLView class sets up an OpenGL ES context, using an instance of the EAGLContext class. The EAGLView instance also creates a timer that triggers a routine for drawing to the EAGLContext.

This book doesn’t cover OpenGL ES applications in depth, but generally you will want to use OpenGL ES to develop any 3D games. Additionally, many 2D immersive applications could take advantage of the power of OpenGL ES to do custom drawing.

Programming the iPhone User Experience

Learn more about this topic from Programming the iPhone User Experience.

This practical book provides you with a hands-on, example-driven tour of Apple's user interface toolkit, UIKit, and some common design patterns for creating gestural interfaces and multi-touch navigation for the iPhone and iPod Touch. You'll learn how to build applications with Apple's Cocoa Touch frameworks that put the needs of mobile users front and center.

See what you'll learn


Tags:
0 Subscribe


0 Replies