Download - Creating Container View Controllers
![Page 2: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/2.jpg)
Bob McCuneAbout...
‣MN Developer and Instructor‣Owner of TapHarmonic, LLC.‣Founded Minnesota CocoaHeads in 2008
![Page 3: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/3.jpg)
What will I learn?Agenda
‣View Controller Overview‣Custom Containers Before iOS 5‣ iOS 5’s View Controller Containment API‣Custom Container Demo
![Page 4: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/4.jpg)
View ControllerOverview
![Page 5: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/5.jpg)
View Controller OverviewWhat is a View Controller?
‣Focal point of most iOS app development‣Key Responsibilities:‣De!nes the application work"ow‣Manages a view hierarchy‣ Programmatically
‣ NIB and/or Storyboard
‣Plays the MVC “Controller” role...
![Page 6: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/6.jpg)
View Controller: The “C” in MVCUnderstanding MVC
Controller
View
User ActionsUpdate State
Model
![Page 7: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/7.jpg)
View Controller: The “C” in MVCUnderstanding MVC
Controller
View
Update UIState Changed
Model
![Page 8: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/8.jpg)
Core iOS Design PatternMVC Bene!ts
‣Clean separation of concerns‣Simpli!es development‣Provides for greater reusability‣ Improves quality
‣Allows us to standardize the behavior and responsibilities at each tier
![Page 9: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/9.jpg)
Standardized BehaviorUIViewController Lifecycle
‣ Rotation Callbacks- (void)willRotateToInterfaceOrientation:- (void)willAnimateRotationToInterfaceOrientation:- (void)didRotateFromInterfaceOrientation:
‣ Loading Callbacks- (void)viewDidLoad;- (void)viewDidUnload;
‣ Appearance Callbacks- (void)viewWillAppear:- (void)viewDidAppear:- (void)viewWillDisappear:- (void)viewDidDisappear:
![Page 10: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/10.jpg)
Container vs ContentView Controller Types
Container Controllers‣ Manages a hierarchy of child view controllersUITabBarControllerUINavigationControllerUISplitViewController
Content Controllers‣ Manage the individual screens within an app‣ Can be used in multiple presentation contexts‣ Manages a “screenful of content”
![Page 11: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/11.jpg)
Seems reasonable...Screenful of Content
![Page 12: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/12.jpg)
Still reasonable?Screenful of Content
![Page 13: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/13.jpg)
What’s a screenful?UISplitViewController
![Page 14: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/14.jpg)
One Screen, Multiple ControllersWhy Create Custom Containers?
‣Aesthetics‣Create a custom application "ow
![Page 15: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/15.jpg)
Custom ContainersThe heartbreaking true story
Pre - iOS 5
![Page 16: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/16.jpg)
Faulty AssumptionsCustom Containers
Static Logo
![Page 17: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/17.jpg)
Faulty AssumptionsCustom Containers
Static Logo
![Page 18: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/18.jpg)
Faulty AssumptionsCustom Containers
Static Logo
![Page 19: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/19.jpg)
Faulty AssumptionsCustom Containers
Static Logo
No you can’t!
![Page 20: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/20.jpg)
Custom Container FailWhat’s the problem?
‣Broken View Controller Hierarchy
‣ Rotation Callbacks- (void)willRotateToInterfaceOrientation:- (void)willAnimateRotationToInterfaceOrientation:- (void)didRotateFromInterfaceOrientation:
‣ Appearance Callbacks- (void)viewWillAppear:- (void)viewDidAppear:- (void)viewWillDisappear:- (void)viewDidDisappear:
![Page 21: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/21.jpg)
Ugly OptionsHow do you !x it?
Create a MonstrosityControllerNot practical
Create non-UIViewController controllersNot scalable
Create container and forward callbacksIncomplete and ugly
![Page 22: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/22.jpg)
View Controller Containment
![Page 23: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/23.jpg)
View vs View ControllerObject Hierarchies
Window
Root View
Tab Bar
NavBar
Segmented
View Hierarchy
![Page 24: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/24.jpg)
View vs View ControllerObject Hierarchies
View Controller Hierarchy
UITabBarController
UINavigationController
ContentViewController
![Page 25: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/25.jpg)
Simple, but subtleView Controller Containment
Child View Controller Callbacks- (void)willMoveToParentViewController:(UIViewController *)parent;- (void)didMoveToParentViewController:(UIViewController *)parent;
Adding and removing child controllers- (void)addChildViewController:(UIViewController *)controller;- (void)removeFromParentViewController;
Accessing the children@property(nonatomic,readonly) NSArray *children;
![Page 26: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/26.jpg)
Adding a Child View ControllerContainment API Usage
[self addChildViewController:controller];[self.view addSubview:controller.view];[controller didMoveToParentViewController:self];
ParentViewController
ChildViewController view
view
willMove
![Page 27: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/27.jpg)
Adding a Child View ControllerContainment API Usage
[self addChildViewController:controller];[self.view addSubview:controller.view];[controller didMoveToParentViewController:self];
ParentViewController
ChildViewController view
view
![Page 28: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/28.jpg)
didMove
Adding a Child View ControllerContainment API Usage
[self addChildViewController:controller];[self.view addSubview:controller.view];[controller didMoveToParentViewController:self];
ParentViewController
ChildViewController view
view
![Page 29: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/29.jpg)
willMove
Removing a Child View ControllerContainment API Usage
ParentViewController
ChildViewController view
view
[controller willMoveToParentViewController:nil];[controller.view removeFromSuperview];[controller removeFromParentViewController];
![Page 30: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/30.jpg)
Removing a Child View ControllerContainment API Usage
ParentViewController
ChildViewController view
view
[controller willMoveToParentViewController:nil];[controller.view removeFromSuperview];[controller removeFromParentViewController];
![Page 31: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/31.jpg)
didMove
Removing a Child View ControllerContainment API Usage
ParentViewController
ChildViewController view
view
[controller willMoveToParentViewController:nil];[controller.view removeFromSuperview];[controller removeFromParentViewController];
![Page 32: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/32.jpg)
Simplifying TransitionsView Controller 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 simpli!es and normalizes transitioning
![Page 33: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/33.jpg)
- (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]; }];}
pushViewController:animated:Cloning UINavigationController
![Page 34: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/34.jpg)
popViewControllerAnimated:Cloning UINavigationController
- (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;}
![Page 35: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/35.jpg)
Fine Tuning ContainmentDisabling Auto Forwarding
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { return NO;}
• Control timing of appearance and rotation callbacks• Useful override in complex containment scenarios
![Page 36: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/36.jpg)
Common MistakesAvoiding
![Page 37: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/37.jpg)
Simple API, Common ProblemsCommon Mistakes
‣Outside Callers‣Disobedient Children‣Meddling Parents
![Page 38: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/38.jpg)
Drive-by AdoptionOutside Callers
ModalViewController
ChildViewController
RootViewController
- (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];}
![Page 39: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/39.jpg)
Parents make the rulesDisobedient Children
- (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller];
CustomContainerController
CustomContainerController
OtherViewController
controller.view.frame = CGRectMake(0, 0, 320, 480); [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self];}
- (void)didMoveToParentViewController:(UIViewController *)parent { self.view.frame = CGRectMake(0, 260, 320, 220); [parent.view addSubview:self.view];}
ChildViewController
ChildViewController
![Page 40: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/40.jpg)
Parents make the rulesDisobedient Children
- (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller];
CustomContainerController
CustomContainerController
OtherViewController
controller.view.frame = CGRectMake(0, 0, 320, 480); [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self];}
- (void)didMoveToParentViewController:(UIViewController *)parent { self.view.frame = CGRectMake(0, 260, 320, 220); [parent.view addSubview:self.view];}
ChildViewController
ChildViewController
![Page 41: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/41.jpg)
Parents make the rulesDisobedient Children
- (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller];
CustomContainerController
OtherViewController
CustomContainerController
[controller didMoveToParentViewController:self];}
ChildViewController
controller.view.frame = CGRectMake(0, 260, 320, 220); [self.view addSubview:controller.view];
![Page 42: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/42.jpg)
Let children be childrenMeddling Parents
ParentViewController
ChildViewController
![Page 43: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/43.jpg)
- (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;}
ParentViewController
Let children be childrenMeddling Parents
ParentViewController
ChildViewController
![Page 44: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/44.jpg)
- (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;}
ChildViewController
Let children be childrenMeddling Parents
ParentViewController
ChildViewController
![Page 45: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/45.jpg)
Demo
![Page 46: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/46.jpg)
View Controller Containment FTW!Summary
‣Simple, but subtle API. Easy to make mistakes.‣Need to understand UIViewController internals‣Small, but important, enhancements in iOS 6
![Page 47: Creating Container View Controllers](https://reader036.vdocuments.us/reader036/viewer/2022062315/5555bfd7d8b42afe5d8b5254/html5/thumbnails/47.jpg)
Resources
Presentation Materialshttp://www.slideshare.net/bobmccune/https://github.com/tapharmonic/
WWDC 2011: Implementing View Controller Containmenthttps://developer.apple.com/videos/wwdc/2011/?id=102
WWDC 2012: The Evolution of View Controllers on iOShttps://developer.apple.com/videos/wwdc/2012/?id=236
BobMcCune.com @bobmccune