Build a view controller in storyboards, configure it with custom views, and fill those views with your app’s data.
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.
To define a content view controller, start by subclassing
UIView. If your interface includes a table view or collection view, subclass
UICollection 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
UIView 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.
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.
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
view 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.
For information about the target-action design pattern and how to handle control-related events, see
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
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:
It creates each view using the view’s
It connects views to the corresponding actions and outlets in the view controller.
It calls the
awakemethod of each view and the view controller.
It assigns the view hierarchy to view controller’s
It calls the view controller’s
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:
It updates the view controller's trait collection based on the target window.
It calls the
viewmethod to let you know the view controller’s view is about to appear onscreen.
If needed, it updates the current layout margins and calls the
Layout Margins Did Change()
If needed, it updates the safe area insets and calls the
Safe Area Insets Did Change()
It calls the
Will Layout Subviews()
It updates the layout of the view hierarchy.
It calls the
Did Layout Subviews()
It displays the views onscreen.
It calls the view controller’s
Update the content of your views in the
view 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
trait 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
view, 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
view method. For more information about the available traits, see