Article

Displaying and Managing Views with a View Controller

Build a view controller in storyboards, configure it with custom views, and fill those views with your app’s data.

Overview

In the model-view-controller design paradigm, a view controller fits between the view objects that present information onscreen and the data objects that store your app's content. Specifically, a view controller manages a view hierarchy and the state information needed to keep those views up-to-date. Every UIKit app relies heavily on view controllers to present content, and you frequently define custom view controllers to manage your views and UI-related logic.

Most custom view controllers you create are content view controllers—that is, the view controller owns all of its views and manages interactions with those views. Use content view controllers to present your app’s custom content onscreen, and use your view controller object to manage the transfer of data to and from your custom views.

An illustration of the relationship between a view controller, its views, and the data objects from your app.

To define a content view controller, start by subclassing UIViewController. If your interface includes a table view or collection view, subclass UITableViewController or UICollectionViewController instead. New Xcode projects include one or more content view controllers classes for you to modify, and you can add more.

Add Views to Your View Controller

UIViewController contains a content view, accessible from the view property, which serves as the root view of its view hierarchy. To that root view, you add the custom views you need to present your interface. In storyboards, you add views by dragging them onto the view controller scene. For example, the following figure shows a view controller with an image view and button on an iPhone.

An image of a view controller interface that contains an image view and button.

After adding views to a view controller, always add Auto Layout constraints to set the size and position of those views. Constraints are rules that specify how to size and position each view relative to its parent or sibling view, and they ensure that your views automatically adapt to different environments and devices. For more information, see View Layout.

Store References to Important Views

At runtime, you may need to access views from your view controller's code. For example, you might want to fetch the text in a text view or change the image in an image view. For that, you need a reference to the view in your view hierarchy. You create those references using outlets.

An outlet is a property in your view controller that includes the IBOutlet keyword. The presence of that keyword tells Xcode to expose that property in your storyboard. The following example code shows the definitions for two outlets. In Swift, include the weak keyword to prevent your view controller from holding a second strong reference to the view—the first originates from the view hierarchy itself.

@IBOutlet weak var imageView : UIImageView?
@IBOutlet weak var button : UIButton?

In your storyboard, connect each outlet to the corresponding view, as described in Add an outlet connection to send a message to a UI object. You do not need to store references to all views in your view hierarchy; store references only to the views you modify later.

When you instantiate a view controller, UIKit reconnects any outlets that you configured in your storyboard. UIKit reestablishes these connections before calling your view controller’s viewDidLoad() method, so you can access the objects in those properties from that method. If you create any views programmatically, you must explicitly assign those views to the appropriate properties of your view controller

Handle Events Occurring in Views and Controls

Controls use the target-action design pattern to report user interactions, and some views post notifications or call delegate methods in response to changes. A view controller needs to know about many of these interactions so it can update its views, and you have several ways to make that happen:

  • Implement delegate and action methods in your view controller. This option is simple and easy to implement, but it offers less flexiblity and makes it harder to test and validate your code.

  • Implement delegate and action methods in a class extension on your view controller. This option separates your event-handling code from the rest of your view controller, making it easier to test and validate that code.

  • Implement delegate and action methods in dedicated objects that then forward relevant information to your view controller. This option offers the most flexibility and reusability. The separation of responsibilities also makes it easier to write unit tests.

To respond to user interactions with controls, define an action method with one of the signatures shown in the following code listing. In your method definition, you may replace the generic reference to UIControl with a more specific control class.

@IBAction func doSomething()
@IBAction func doSomething(sender: UIControl)
@IBAction func doSomething(sender: UIControl, forEvent event: UIEvent)

For information about the target-action design pattern and how to handle control-related events, see UIControl.

Prepare Your Views to Appear Onscreen

UIKit gives you several opportunities to configure your view controller and views before displaying them onscreen. When you instantiate your view controller from a storyboard, UIKit creates that object using its init(coder:) method.

When you present a view controller onscreen, UIKit must first load and configure the corresponding views, which it does using the following sequence of steps:

  1. It creates each view using the view’s init(coder:) method.

  2. It connects views to the corresponding actions and outlets in the view controller.

  3. It calls the awakeFromNib() method of each view and the view controller.

  4. It assigns the view hierarchy to view controller’s view property.

  5. It calls the view controller’s viewDidLoad() method.

At load time, perform only the one-time configuration steps you need to prepare the view controller for use. Use load time to create and configure any additional views that aren't part of your storyboard. Don't perform tasks that must happen each time your view controller appears onscreen. For example, don't start animations or update the values of views.

Perform any final view-related tasks shortly before your views appear onscreen. UIKit notifies the owning view controller when its views are about to appear onscreen, and updates the layout of those views to fit the current environment, by calling the following methods in order:

  1. It updates the view controller's trait collection based on the target window.

  2. It calls the viewWillAppear(_:) method to let you know the view controller’s view is about to appear onscreen.

  3. If needed, it updates the current layout margins and calls the viewLayoutMarginsDidChange() method.

  4. If needed, it updates the safe area insets and calls the viewSafeAreaInsetsDidChange() method.

  5. It calls the viewWillLayoutSubviews() method.

  6. It updates the layout of the view hierarchy.

  7. It calls the viewDidLayoutSubviews() method.

  8. It displays the views onscreen.

  9. It calls the view controller’s viewDidAppear(_:) method.

Update the content of your views in the viewWillAppear(_:) method of your view controller. Changing the content of many views triggers an automatic layout update, so making changes in that method avoids an additional layout step. When making changes, you may use the view controller's traitCollection property to access information about the current environment, such as the display scale or the vertical and horizontal size classes. Although you can access traits earlier than viewWillAppear(_:), traits aren't guaranteed to be final until that method. In iOS 12 and earlier, UIKit only provides a partial set of traits at load time, and doesn't provide a complete set of traits until the viewWillAppear(_:) method. For more information about the available traits, see UITraitCollection.

See Also

Content View Controllers

Showing and Hiding View Controllers

Display view controllers using different techniques, and pass data between them during transitions.

class UIViewController

An object that manages a view hierarchy for your UIKit app.

class UITableViewController

A view controller that specializes in managing a table view.

class UICollectionViewController

A view controller that specializes in managing a collection view.

protocol UIContentContainer

A set of methods for adapting the contents of your view controllers to size and trait changes.