SlideShare uma empresa Scribd logo
1 de 47
Baixar para ler offline
Creating
Container View
   Controllers

        http://bobmccune.com
About...
Bob McCune
 ‣ MN Developer and Instructor
 ‣ Owner of TapHarmonic, LLC.
 ‣ Founded Minnesota CocoaHeads in 2008
Agenda
What will I learn?
‣ View Controller Overview
‣ Custom Containers Before iOS 5
‣ iOS 5’s View Controller Containment API
‣ Custom Container Demo
View Controller
   Overview
What is a View Controller?
View Controller Overview
‣ Focal point of most iOS app development
‣ Key Responsibilities:
  ‣ Defines the application workflow
  ‣ Manages a view hierarchy
    ‣ Programmatically
    ‣ NIB and/or Storyboard
‣ Plays the MVC “Controller” role...
Understanding MVC
View Controller: The “C” in MVC



   Model                                  View




    Update State   Controller     User Actions
Understanding MVC
View Controller: The “C” in MVC



   Model                                View




  State Changed    Controller     Update UI
MVC Benefits
Core iOS Design Pattern
 ‣ Clean separation of concerns
    ‣ Simplifies development
    ‣ Provides for greater reusability
    ‣ Improves quality
 ‣ Allows us to standardize the behavior and
   responsibilities at each tier
UIViewController Lifecycle
Standardized Behavior
‣ Loading Callbacks
 - (void)viewDidLoad;
 - (void)viewDidUnload;

‣ Appearance Callbacks
 -   (void)viewWillAppear:
 -   (void)viewDidAppear:
 -   (void)viewWillDisappear:
 -   (void)viewDidDisappear:

‣ Rotation Callbacks
 - (void)willRotateToInterfaceOrientation:
 - (void)willAnimateRotationToInterfaceOrientation:
 - (void)didRotateFromInterfaceOrientation:
View Controller Types
Container vs Content
Container Controllers
‣ Manages a hierarchy of child view controllers

 UITabBarController
 UINavigationController
 UISplitViewController

Content Controllers
‣ Manage the individual screens within an app

‣ Can be used in multiple presentation contexts

‣ Manages a “screenful of content”
Screenful of Content
Seems reasonable...
Screenful of Content
Still reasonable?
UISplitViewController
What’s a screenful?
Why Create Custom Containers?
One Screen, Multiple Controllers
 ‣ Aesthetics
 ‣ Create a custom application flow
 Pre  -­  iOS  5
Custom Containers
The heartbreaking true story
Custom Containers
Faulty Assumptions


                     Static  Logo
Custom Containers
Faulty Assumptions


                     Static  Logo
Custom Containers
Faulty Assumptions


                     Static  Logo
Custom Containers
Faulty Assumptions can’t!
            No you


                   Static  Logo
What’s the problem?
Custom Container Fail
‣ Appearance Callbacks
 -   (void)viewWillAppear:
 -   (void)viewDidAppear:
 -   (void)viewWillDisappear:
 -   (void)viewDidDisappear:

‣ Rotation Callbacks
 - (void)willRotateToInterfaceOrientation:
 - (void)willAnimateRotationToInterfaceOrientation:
 - (void)didRotateFromInterfaceOrientation:

‣ Broken View Controller Hierarchy
How do you fix it?
Ugly Options
Create a MonstrosityController
Not practical
Create non-UIViewController controllers
Not scalable
Create container and forward callbacks
Incomplete and ugly
View Controller Containment
Object Hierarchies
View vs View Controller

    View Hierarchy

           Window



          Root View



               NavBar



                 Segmented



     Tab Bar
Object Hierarchies
View vs View Controller
                          View Controller Hierarchy

                               UITabBarController




                                   UINavigationController




                                        ContentViewController
View Controller Containment
Simple, but subtle
Adding and removing child controllers
- (void)addChildViewController:(UIViewController *)controller;
- (void)removeFromParentViewController;


Accessing the children
@property(nonatomic,readonly) NSArray *children;


Child View Controller Callbacks
- (void)willMoveToParentViewController:(UIViewController *)parent;
- (void)didMoveToParentViewController:(UIViewController *)parent;
Containment API Usage
Adding a Child View Controller
   [self addChildViewController:controller];
   [self.view addSubview:controller.view];
   [controller didMoveToParentViewController:self];

                                         view
           ParentViewController


willMove


                                  view
           ChildViewController
Containment API Usage
Adding a Child View Controller
 [self addChildViewController:controller];
 [self.view addSubview:controller.view];
 [controller didMoveToParentViewController:self];

                           view
    ParentViewController




                           view
    ChildViewController
Containment API Usage
Adding a Child View Controller
   [self addChildViewController:controller];
   [self.view addSubview:controller.view];
   [controller didMoveToParentViewController:self];

                                 view
          ParentViewController


didMove


                                 view
          ChildViewController
Containment API Usage
Removing a Child View Controller
   [controller willMoveToParentViewController:nil];
   [controller.view removeFromSuperview];
   [controller removeFromParentViewController];

                                  view
           ParentViewController


willMove


                                  view
           ChildViewController
Containment API Usage
Removing a Child View Controller
 [controller willMoveToParentViewController:nil];
 [controller.view removeFromSuperview];
 [controller removeFromParentViewController];

                                  view
    ParentViewController




                           view
    ChildViewController
Containment API Usage
Removing a Child View Controller
   [controller willMoveToParentViewController:nil];
   [controller.view removeFromSuperview];
   [controller removeFromParentViewController];

                                        view
          ParentViewController


didMove


                                 view
          ChildViewController
View Controller Transitions
Simplifying Transitions
- (void)transitionFromViewController:(UIViewController *)fromVC
                    toViewController:(UIViewController *)toVC
                            duration:(NSTimeInterval)duration
                             options:(UIViewAnimationOptions)options
                          animations:(void (^)(void))animations
                          completion:(void (^)(BOOL finished))block;

‣ Convenience method for view controller transitions
‣ Optional, but simplifies and normalizes transitioning
Cloning UINavigationController
pushViewController:animated:
- (void)pushViewController:(UIViewController *)toViewController animated:(BOOL)animated {

    UIViewController *fromViewController = [self.stack topObject];
    toViewController.view.frame = CGRectMake(width, 0.f, width, height);

    [self addChildViewController:toViewController];

    NSTimeInterval duration = animated ? 0.3f : 0.f;

    [self transitionFromViewController:fromViewController
                      toViewController:toViewController
                              duration:duration
                                options:UIViewAnimationCurveEaseInOut
                            animations:^{
                              CGRect frame = CGRectMake(-width, 0.f, width, height);
                              fromViewController.view.frame = frame;
                            }
                            completion:^(BOOL complete) {
                              [toViewController didMoveToParentViewController:self];
                              [self.stack pushObject:toViewController];
                            }];
}
Cloning UINavigationController
popViewControllerAnimated:
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {

    UIViewController *fromViewController = [self.stack popObject];
    UIViewController *toViewController = [self.stack topObject];

    [fromViewController willMoveToParentViewController:nil];

    NSTimeInterval duration = animated ? 0.3f : 0.0f;

    [self transitionFromViewController:fromViewController
                      toViewController:toViewController
                              duration:duration
                                options:UIViewAnimationOptionCurveEaseInOut
                            animations:^{
                                 CGRect frame = CGRectMake(width, 0.f, width, height);
                                 fromViewController.view.frame = frame;
                            }
                            completion:^(BOOL complete) {
                                 [fromViewController removeFromParentViewController];
                            }];

    return fromViewController;
}
Disabling Auto Forwarding
Fine Tuning Containment
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return NO;
}

• Control timing of appearance and rotation callbacks
• Useful override in complex containment scenarios
Avoiding
 Common Mistakes
Common Mistakes
Simple API, Common Problems
 ‣ Outside Callers
 ‣ Disobedient Children
 ‣ Meddling Parents
Outside Callers
  Drive-by Adoption

                              ModalViewController


     RootViewController


                              ChildViewController




- (IBAction)showModalView:(id)sender {
  ModalViewController *modalController = [ModalViewController controller];
  [self presentViewController:modalController animated:YES completion:nil];
  ChildViewController *childController = [ChildViewController controller];
	 [modalController addChildViewController:childController];
	 [modalController addSubview:childController.view];
}
Disobedient Children
Parents make the rules

                            CustomContainerController
    OtherViewController
                               ChildViewController




CustomContainerController
-    (void)showChildViewController:(UIViewController *)controller {
	    [self addChildViewController:controller];
	    controller.view.frame = CGRectMake(0, 0, 320, 480);
     [controller didMoveToParentViewController:self];
}    [self.view addSubview:controller.view];

ChildViewController
- (void)didMoveToParentViewController:(UIViewController *)parent {
    self.view.frame = CGRectMake(0, 260, 320, 220);
    [parent.view addSubview:self.view];
}
Disobedient Children
Parents make the rules

                            CustomContainerController
    OtherViewController
                               ChildViewController




CustomContainerController
-    (void)showChildViewController:(UIViewController *)controller {
	    [self addChildViewController:controller];
	    controller.view.frame = CGRectMake(0, 0, 320, 480);
     [controller didMoveToParentViewController:self];
}    [self.view addSubview:controller.view];

ChildViewController
- (void)didMoveToParentViewController:(UIViewController *)parent {
    self.view.frame = CGRectMake(0, 260, 320, 220);
    [parent.view addSubview:self.view];
}
Disobedient Children
Parents make the rules

                         CustomContainerController
 OtherViewController
                            ChildViewController




CustomContainerController
- (void)showChildViewController:(UIViewController *)controller {
	 [self addChildViewController:controller];
  controller.view.frame = CGRectMake(0, 260, 320, 220);
  [self.view addSubview:controller.view];
	 [controller didMoveToParentViewController:self];
}
Meddling Parents
Let children be children


     ParentViewController




     ChildViewController
Meddling Parents
Let children be children


       ParentViewController




        ChildViewController




ParentViewController
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation
                                         duration:(NSTimeInterval)duration {
	 self.childViewController.button1.frame = // button 1 frame for orientation;
	 self.childViewController.button2.frame = // button 2 frame for orientation;
	 self.childViewController.button3.frame = // button 3 frame for orientation;
}
Meddling Parents
Let children be children


       ParentViewController




        ChildViewController




ChildViewController
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation
                                         duration:(NSTimeInterval)duration {
	 self.button1.frame = // button 1 frame for orientation;
	 self.button2.frame = // button 2 frame for orientation;
	 self.button3.frame = // button 3 frame for orientation;
}
Demo
Summary
View Controller Containment FTW!
 ‣ Simple, but subtle API. Easy to make mistakes.
 ‣ Need to understand UIViewController internals
 ‣ Small, but important, enhancements in iOS 6
Resources
Presentation Materials
http://www.slideshare.net/bobmccune/
https://github.com/tapharmonic/

WWDC 2011: Implementing View Controller Containment
https://developer.apple.com/videos/wwdc/2011/?id=102

WWDC 2012: The Evolution of View Controllers on iOS
https://developer.apple.com/videos/wwdc/2012/?id=236




    BobMcCune.com                                 @bobmccune

Mais conteúdo relacionado

Mais procurados

Ionic adventures - Hybrid Mobile App Development rocks
Ionic adventures - Hybrid Mobile App Development rocksIonic adventures - Hybrid Mobile App Development rocks
Ionic adventures - Hybrid Mobile App Development rocksJuarez Filho
 
UI5con 2018: News from Control Development
UI5con 2018: News from Control DevelopmentUI5con 2018: News from Control Development
UI5con 2018: News from Control DevelopmentAndreas Kunz
 
Atomic Designは「マルチ」で真価を発揮する
Atomic Designは「マルチ」で真価を発揮するAtomic Designは「マルチ」で真価を発揮する
Atomic Designは「マルチ」で真価を発揮するYukiya Nakagawa
 
Android Wear: A Developer's Perspective
Android Wear: A Developer's PerspectiveAndroid Wear: A Developer's Perspective
Android Wear: A Developer's PerspectiveVin Lim
 
Meetup angular http client
Meetup angular http clientMeetup angular http client
Meetup angular http clientGaurav Madaan
 
Predictable Web Apps with Angular and Redux
Predictable Web Apps with Angular and ReduxPredictable Web Apps with Angular and Redux
Predictable Web Apps with Angular and ReduxFITC
 
AngularJS for Beginners
AngularJS for BeginnersAngularJS for Beginners
AngularJS for BeginnersEdureka!
 
Mobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMohammad Shaker
 
Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.Mohammad Shaker
 
Adding User Management to Node.js
Adding User Management to Node.jsAdding User Management to Node.js
Adding User Management to Node.jsDev_Events
 
WebView Development Pitfalls
WebView Development PitfallsWebView Development Pitfalls
WebView Development Pitfallstonypai
 
I/O Rewind 215: What's new in Android
I/O Rewind 215: What's new in AndroidI/O Rewind 215: What's new in Android
I/O Rewind 215: What's new in AndroidSittiphol Phanvilai
 
Support Design Library
Support Design LibrarySupport Design Library
Support Design LibraryTaeho Kim
 
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)🎤 Hanno Embregts 🎸
 
Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016
Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016
Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016Loïc Knuchel
 
Multi Window in Android N
Multi Window in Android NMulti Window in Android N
Multi Window in Android NTaeho Kim
 

Mais procurados (20)

Ionic adventures - Hybrid Mobile App Development rocks
Ionic adventures - Hybrid Mobile App Development rocksIonic adventures - Hybrid Mobile App Development rocks
Ionic adventures - Hybrid Mobile App Development rocks
 
UI5con 2018: News from Control Development
UI5con 2018: News from Control DevelopmentUI5con 2018: News from Control Development
UI5con 2018: News from Control Development
 
Atomic Designは「マルチ」で真価を発揮する
Atomic Designは「マルチ」で真価を発揮するAtomic Designは「マルチ」で真価を発揮する
Atomic Designは「マルチ」で真価を発揮する
 
Android Wear: A Developer's Perspective
Android Wear: A Developer's PerspectiveAndroid Wear: A Developer's Perspective
Android Wear: A Developer's Perspective
 
Meetup angular http client
Meetup angular http clientMeetup angular http client
Meetup angular http client
 
Angular
AngularAngular
Angular
 
Predictable Web Apps with Angular and Redux
Predictable Web Apps with Angular and ReduxPredictable Web Apps with Angular and Redux
Predictable Web Apps with Angular and Redux
 
PhotoFlipCardView
PhotoFlipCardViewPhotoFlipCardView
PhotoFlipCardView
 
AngularJS for Beginners
AngularJS for BeginnersAngularJS for Beginners
AngularJS for Beginners
 
Create twitter-ios-app
Create twitter-ios-appCreate twitter-ios-app
Create twitter-ios-app
 
Mobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhone
 
Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.
 
JavaScript : One To Many
JavaScript : One To ManyJavaScript : One To Many
JavaScript : One To Many
 
Adding User Management to Node.js
Adding User Management to Node.jsAdding User Management to Node.js
Adding User Management to Node.js
 
WebView Development Pitfalls
WebView Development PitfallsWebView Development Pitfalls
WebView Development Pitfalls
 
I/O Rewind 215: What's new in Android
I/O Rewind 215: What's new in AndroidI/O Rewind 215: What's new in Android
I/O Rewind 215: What's new in Android
 
Support Design Library
Support Design LibrarySupport Design Library
Support Design Library
 
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
 
Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016
Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016
Ionic2, les développeurs web à l'assaut du mobile, BDX I/O le 21/10/2016
 
Multi Window in Android N
Multi Window in Android NMulti Window in Android N
Multi Window in Android N
 

Destaque

Core Animation
Core AnimationCore Animation
Core AnimationBob McCune
 
Composing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationComposing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationBob McCune
 
Objective-C for Java Developers
Objective-C for Java DevelopersObjective-C for Java Developers
Objective-C for Java DevelopersBob McCune
 
Drawing with Quartz on iOS
Drawing with Quartz on iOSDrawing with Quartz on iOS
Drawing with Quartz on iOSBob McCune
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV FoundationBob McCune
 
Mastering Media with AV Foundation
Mastering Media with AV FoundationMastering Media with AV Foundation
Mastering Media with AV FoundationChris Adamson
 
Quartz 2D with Swift 3
Quartz 2D with Swift 3Quartz 2D with Swift 3
Quartz 2D with Swift 3Bob McCune
 
Starting Core Animation
Starting Core AnimationStarting Core Animation
Starting Core AnimationJohn Wilker
 
Building Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBuilding Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBob McCune
 
20 iOS developer interview questions
20 iOS developer interview questions20 iOS developer interview questions
20 iOS developer interview questionsArc & Codementor
 
iOS Developer Interview Questions
iOS Developer Interview QuestionsiOS Developer Interview Questions
iOS Developer Interview QuestionsClark Davidson
 
Core Graphics & Core Animation
Core Graphics & Core AnimationCore Graphics & Core Animation
Core Graphics & Core AnimationAndreas Blick
 
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineForward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineChris Adamson
 
try! Swift - Advanced Graphics with Core Animation
try! Swift - Advanced Graphics with Core Animationtry! Swift - Advanced Graphics with Core Animation
try! Swift - Advanced Graphics with Core AnimationTim Oliver
 
Designing better user interfaces
Designing better user interfacesDesigning better user interfaces
Designing better user interfacesJohan Ronsse
 
iOS Coding Best Practices
iOS Coding Best PracticesiOS Coding Best Practices
iOS Coding Best PracticesJean-Luc David
 
iOS design: a case study
iOS design: a case studyiOS design: a case study
iOS design: a case studyJohan Ronsse
 
iOS Scroll Performance
iOS Scroll PerformanceiOS Scroll Performance
iOS Scroll PerformanceKyle Sherman
 

Destaque (20)

Core Animation
Core AnimationCore Animation
Core Animation
 
Composing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationComposing and Editing Media with AV Foundation
Composing and Editing Media with AV Foundation
 
Objective-C for Java Developers
Objective-C for Java DevelopersObjective-C for Java Developers
Objective-C for Java Developers
 
Drawing with Quartz on iOS
Drawing with Quartz on iOSDrawing with Quartz on iOS
Drawing with Quartz on iOS
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV Foundation
 
Mastering Media with AV Foundation
Mastering Media with AV FoundationMastering Media with AV Foundation
Mastering Media with AV Foundation
 
Quartz 2D with Swift 3
Quartz 2D with Swift 3Quartz 2D with Swift 3
Quartz 2D with Swift 3
 
Starting Core Animation
Starting Core AnimationStarting Core Animation
Starting Core Animation
 
Building Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBuilding Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngine
 
Animation in iOS
Animation in iOSAnimation in iOS
Animation in iOS
 
20 iOS developer interview questions
20 iOS developer interview questions20 iOS developer interview questions
20 iOS developer interview questions
 
iOS Developer Interview Questions
iOS Developer Interview QuestionsiOS Developer Interview Questions
iOS Developer Interview Questions
 
Core Graphics & Core Animation
Core Graphics & Core AnimationCore Graphics & Core Animation
Core Graphics & Core Animation
 
Graphics Libraries
Graphics LibrariesGraphics Libraries
Graphics Libraries
 
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineForward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
 
try! Swift - Advanced Graphics with Core Animation
try! Swift - Advanced Graphics with Core Animationtry! Swift - Advanced Graphics with Core Animation
try! Swift - Advanced Graphics with Core Animation
 
Designing better user interfaces
Designing better user interfacesDesigning better user interfaces
Designing better user interfaces
 
iOS Coding Best Practices
iOS Coding Best PracticesiOS Coding Best Practices
iOS Coding Best Practices
 
iOS design: a case study
iOS design: a case studyiOS design: a case study
iOS design: a case study
 
iOS Scroll Performance
iOS Scroll PerformanceiOS Scroll Performance
iOS Scroll Performance
 

Semelhante a Creating Container View Controllers

Using view controllers wisely
Using view controllers wiselyUsing view controllers wisely
Using view controllers wiselydefagos
 
Intro to UIKit • Made by Many
Intro to UIKit • Made by ManyIntro to UIKit • Made by Many
Intro to UIKit • Made by Manykenatmxm
 
Session 15 - Working with Image, Scroll, Collection, Picker, and Web View
Session 15  - Working with Image, Scroll, Collection, Picker, and Web ViewSession 15  - Working with Image, Scroll, Collection, Picker, and Web View
Session 15 - Working with Image, Scroll, Collection, Picker, and Web ViewVu Tran Lam
 
iPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてiPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてKyosuke Takayama
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder BehindJohn Wilker
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingNatasha Murashev
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818Shahzain Saeed
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftPROIDEA
 
App coordinators in iOS
App coordinators in iOSApp coordinators in iOS
App coordinators in iOSUptech
 
Use case driven architecture
Use case driven architectureUse case driven architecture
Use case driven architectureBohdan Orlov
 
CocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIViewCocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIViewCocoaHeads France
 
Using a model view-view model architecture for iOS apps
Using a model view-view model architecture for iOS appsUsing a model view-view model architecture for iOS apps
Using a model view-view model architecture for iOS appsallanh0526
 
아이폰강의(5) pdf
아이폰강의(5) pdf아이폰강의(5) pdf
아이폰강의(5) pdfsunwooindia
 

Semelhante a Creating Container View Controllers (20)

I os 11
I os 11I os 11
I os 11
 
Using view controllers wisely
Using view controllers wiselyUsing view controllers wisely
Using view controllers wisely
 
004
004004
004
 
Intro to UIKit • Made by Many
Intro to UIKit • Made by ManyIntro to UIKit • Made by Many
Intro to UIKit • Made by Many
 
Session 15 - Working with Image, Scroll, Collection, Picker, and Web View
Session 15  - Working with Image, Scroll, Collection, Picker, and Web ViewSession 15  - Working with Image, Scroll, Collection, Picker, and Web View
Session 15 - Working with Image, Scroll, Collection, Picker, and Web View
 
IOS APPs Revision
IOS APPs RevisionIOS APPs Revision
IOS APPs Revision
 
iPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについてiPhoneOS3.1でのカメラAPIについて
iPhoneOS3.1でのカメラAPIについて
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
 
занятие6
занятие6занятие6
занятие6
 
App coordinators in iOS
App coordinators in iOSApp coordinators in iOS
App coordinators in iOS
 
Use case driven architecture
Use case driven architectureUse case driven architecture
Use case driven architecture
 
CocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIViewCocoaHeads Toulouse - Guillaume Cerquant - UIView
CocoaHeads Toulouse - Guillaume Cerquant - UIView
 
Using a model view-view model architecture for iOS apps
Using a model view-view model architecture for iOS appsUsing a model view-view model architecture for iOS apps
Using a model view-view model architecture for iOS apps
 
아이폰강의(5) pdf
아이폰강의(5) pdf아이폰강의(5) pdf
아이폰강의(5) pdf
 
Swf2 ui
Swf2 uiSwf2 ui
Swf2 ui
 
View controllers en iOS
View controllers en iOSView controllers en iOS
View controllers en iOS
 
From mvc to viper
From mvc to viperFrom mvc to viper
From mvc to viper
 

Último

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 

Último (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 

Creating Container View Controllers

  • 1. Creating Container View Controllers http://bobmccune.com
  • 2. About... Bob McCune ‣ MN Developer and Instructor ‣ Owner of TapHarmonic, LLC. ‣ Founded Minnesota CocoaHeads in 2008
  • 3. Agenda What will I learn? ‣ View Controller Overview ‣ Custom Containers Before iOS 5 ‣ iOS 5’s View Controller Containment API ‣ Custom Container Demo
  • 4. View Controller Overview
  • 5. What is a View Controller? View Controller Overview ‣ Focal point of most iOS app development ‣ Key Responsibilities: ‣ Defines the application workflow ‣ Manages a view hierarchy ‣ Programmatically ‣ NIB and/or Storyboard ‣ Plays the MVC “Controller” role...
  • 6. Understanding MVC View Controller: The “C” in MVC Model View Update State Controller User Actions
  • 7. Understanding MVC View Controller: The “C” in MVC Model View State Changed Controller Update UI
  • 8. MVC Benefits Core iOS Design Pattern ‣ Clean separation of concerns ‣ Simplifies development ‣ Provides for greater reusability ‣ Improves quality ‣ Allows us to standardize the behavior and responsibilities at each tier
  • 9. UIViewController Lifecycle Standardized Behavior ‣ Loading Callbacks - (void)viewDidLoad; - (void)viewDidUnload; ‣ Appearance Callbacks - (void)viewWillAppear: - (void)viewDidAppear: - (void)viewWillDisappear: - (void)viewDidDisappear: ‣ Rotation Callbacks - (void)willRotateToInterfaceOrientation: - (void)willAnimateRotationToInterfaceOrientation: - (void)didRotateFromInterfaceOrientation:
  • 10. View Controller Types Container vs Content Container Controllers ‣ Manages a hierarchy of child view controllers UITabBarController UINavigationController UISplitViewController Content Controllers ‣ Manage the individual screens within an app ‣ Can be used in multiple presentation contexts ‣ Manages a “screenful of content”
  • 11. Screenful of Content Seems reasonable...
  • 14. Why Create Custom Containers? One Screen, Multiple Controllers ‣ Aesthetics ‣ Create a custom application flow
  • 15.  Pre  -­  iOS  5 Custom Containers The heartbreaking true story
  • 19. Custom Containers Faulty Assumptions can’t! No you Static  Logo
  • 20. What’s the problem? Custom Container Fail ‣ Appearance Callbacks - (void)viewWillAppear: - (void)viewDidAppear: - (void)viewWillDisappear: - (void)viewDidDisappear: ‣ Rotation Callbacks - (void)willRotateToInterfaceOrientation: - (void)willAnimateRotationToInterfaceOrientation: - (void)didRotateFromInterfaceOrientation: ‣ Broken View Controller Hierarchy
  • 21. How do you fix it? Ugly Options Create a MonstrosityController Not practical Create non-UIViewController controllers Not scalable Create container and forward callbacks Incomplete and ugly
  • 23. Object Hierarchies View vs View Controller View Hierarchy Window Root View NavBar Segmented Tab Bar
  • 24. Object Hierarchies View vs View Controller View Controller Hierarchy UITabBarController UINavigationController ContentViewController
  • 25. View Controller Containment Simple, but subtle Adding and removing child controllers - (void)addChildViewController:(UIViewController *)controller; - (void)removeFromParentViewController; Accessing the children @property(nonatomic,readonly) NSArray *children; Child View Controller Callbacks - (void)willMoveToParentViewController:(UIViewController *)parent; - (void)didMoveToParentViewController:(UIViewController *)parent;
  • 26. Containment API Usage Adding a Child View Controller [self addChildViewController:controller]; [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; view ParentViewController willMove view ChildViewController
  • 27. Containment API Usage Adding a Child View Controller [self addChildViewController:controller]; [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; view ParentViewController view ChildViewController
  • 28. Containment API Usage Adding a Child View Controller [self addChildViewController:controller]; [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; view ParentViewController didMove view ChildViewController
  • 29. Containment API Usage Removing a Child View Controller [controller willMoveToParentViewController:nil]; [controller.view removeFromSuperview]; [controller removeFromParentViewController]; view ParentViewController willMove view ChildViewController
  • 30. Containment API Usage Removing a Child View Controller [controller willMoveToParentViewController:nil]; [controller.view removeFromSuperview]; [controller removeFromParentViewController]; view ParentViewController view ChildViewController
  • 31. Containment API Usage Removing a Child View Controller [controller willMoveToParentViewController:nil]; [controller.view removeFromSuperview]; [controller removeFromParentViewController]; view ParentViewController didMove view ChildViewController
  • 32. View Controller Transitions Simplifying Transitions - (void)transitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))block; ‣ Convenience method for view controller transitions ‣ Optional, but simplifies and normalizes transitioning
  • 33. Cloning UINavigationController pushViewController:animated: - (void)pushViewController:(UIViewController *)toViewController animated:(BOOL)animated { UIViewController *fromViewController = [self.stack topObject]; toViewController.view.frame = CGRectMake(width, 0.f, width, height); [self addChildViewController:toViewController]; NSTimeInterval duration = animated ? 0.3f : 0.f; [self transitionFromViewController:fromViewController toViewController:toViewController duration:duration options:UIViewAnimationCurveEaseInOut animations:^{ CGRect frame = CGRectMake(-width, 0.f, width, height); fromViewController.view.frame = frame; } completion:^(BOOL complete) { [toViewController didMoveToParentViewController:self]; [self.stack pushObject:toViewController]; }]; }
  • 34. Cloning UINavigationController popViewControllerAnimated: - (UIViewController *)popViewControllerAnimated:(BOOL)animated { UIViewController *fromViewController = [self.stack popObject]; UIViewController *toViewController = [self.stack topObject]; [fromViewController willMoveToParentViewController:nil]; NSTimeInterval duration = animated ? 0.3f : 0.0f; [self transitionFromViewController:fromViewController toViewController:toViewController duration:duration options:UIViewAnimationOptionCurveEaseInOut animations:^{ CGRect frame = CGRectMake(width, 0.f, width, height); fromViewController.view.frame = frame; } completion:^(BOOL complete) { [fromViewController removeFromParentViewController]; }]; return fromViewController; }
  • 35. Disabling Auto Forwarding Fine Tuning Containment - (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { return NO; } • Control timing of appearance and rotation callbacks • Useful override in complex containment scenarios
  • 37. Common Mistakes Simple API, Common Problems ‣ Outside Callers ‣ Disobedient Children ‣ Meddling Parents
  • 38. Outside Callers Drive-by Adoption ModalViewController RootViewController ChildViewController - (IBAction)showModalView:(id)sender { ModalViewController *modalController = [ModalViewController controller]; [self presentViewController:modalController animated:YES completion:nil]; ChildViewController *childController = [ChildViewController controller]; [modalController addChildViewController:childController]; [modalController addSubview:childController.view]; }
  • 39. Disobedient Children Parents make the rules CustomContainerController OtherViewController ChildViewController CustomContainerController - (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller]; controller.view.frame = CGRectMake(0, 0, 320, 480); [controller didMoveToParentViewController:self]; } [self.view addSubview:controller.view]; ChildViewController - (void)didMoveToParentViewController:(UIViewController *)parent { self.view.frame = CGRectMake(0, 260, 320, 220); [parent.view addSubview:self.view]; }
  • 40. Disobedient Children Parents make the rules CustomContainerController OtherViewController ChildViewController CustomContainerController - (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller]; controller.view.frame = CGRectMake(0, 0, 320, 480); [controller didMoveToParentViewController:self]; } [self.view addSubview:controller.view]; ChildViewController - (void)didMoveToParentViewController:(UIViewController *)parent { self.view.frame = CGRectMake(0, 260, 320, 220); [parent.view addSubview:self.view]; }
  • 41. Disobedient Children Parents make the rules CustomContainerController OtherViewController ChildViewController CustomContainerController - (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller]; controller.view.frame = CGRectMake(0, 260, 320, 220); [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; }
  • 42. Meddling Parents Let children be children ParentViewController ChildViewController
  • 43. Meddling Parents Let children be children ParentViewController ChildViewController ParentViewController - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration { self.childViewController.button1.frame = // button 1 frame for orientation; self.childViewController.button2.frame = // button 2 frame for orientation; self.childViewController.button3.frame = // button 3 frame for orientation; }
  • 44. Meddling Parents Let children be children ParentViewController ChildViewController ChildViewController - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration { self.button1.frame = // button 1 frame for orientation; self.button2.frame = // button 2 frame for orientation; self.button3.frame = // button 3 frame for orientation; }
  • 45. Demo
  • 46. Summary View Controller Containment FTW! ‣ Simple, but subtle API. Easy to make mistakes. ‣ Need to understand UIViewController internals ‣ Small, but important, enhancements in iOS 6
  • 47. Resources Presentation Materials http://www.slideshare.net/bobmccune/ https://github.com/tapharmonic/ WWDC 2011: Implementing View Controller Containment https://developer.apple.com/videos/wwdc/2011/?id=102 WWDC 2012: The Evolution of View Controllers on iOS https://developer.apple.com/videos/wwdc/2012/?id=236 BobMcCune.com @bobmccune