creating container view controllers

47
http://bobmccune.com Creating Container View Controllers

Upload: bob-mccune

Post on 15-May-2015

44.127 views

Category:

Technology


1 download

DESCRIPTION

Presentation given at 2012 360iDev Conference.

TRANSCRIPT

Page 1: Creating Container View Controllers

http://bobmccune.com

Creating Container View

Controllers

Page 2: Creating Container View Controllers

Bob McCuneAbout...

‣MN Developer and Instructor‣Owner of TapHarmonic, LLC.‣Founded Minnesota CocoaHeads in 2008

Page 3: Creating Container View Controllers

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

View ControllerOverview

Page 5: Creating Container View Controllers

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

View Controller: The “C” in MVCUnderstanding MVC

Controller

View

User ActionsUpdate State

Model

Page 7: Creating Container View Controllers

View Controller: The “C” in MVCUnderstanding MVC

Controller

View

Update UIState Changed

Model

Page 8: Creating Container View Controllers

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

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

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

Seems reasonable...Screenful of Content

Page 12: Creating Container View Controllers

Still reasonable?Screenful of Content

Page 13: Creating Container View Controllers

What’s a screenful?UISplitViewController

Page 14: Creating Container View Controllers

One Screen, Multiple ControllersWhy Create Custom Containers?

‣Aesthetics‣Create a custom application "ow

Page 15: Creating Container View Controllers

Custom ContainersThe heartbreaking true story

 Pre  -­  iOS  5

Page 16: Creating Container View Controllers

Faulty AssumptionsCustom Containers

Static  Logo

Page 17: Creating Container View Controllers

Faulty AssumptionsCustom Containers

Static  Logo

Page 18: Creating Container View Controllers

Faulty AssumptionsCustom Containers

Static  Logo

Page 19: Creating Container View Controllers

Faulty AssumptionsCustom Containers

Static  Logo

No you can’t!

Page 20: Creating Container View Controllers

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

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

View Controller Containment

Page 23: Creating Container View Controllers

View vs View ControllerObject Hierarchies

Window

Root View

Tab Bar

NavBar

Segmented

View Hierarchy

Page 24: Creating Container View Controllers

View vs View ControllerObject Hierarchies

View Controller Hierarchy

UITabBarController

UINavigationController

ContentViewController

Page 25: Creating Container View Controllers

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

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

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

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

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

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

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

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

- (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

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

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

Common MistakesAvoiding

Page 37: Creating Container View Controllers

Simple API, Common ProblemsCommon Mistakes

‣Outside Callers‣Disobedient Children‣Meddling Parents

Page 38: Creating Container View Controllers

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

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

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

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

Let children be childrenMeddling Parents

ParentViewController

ChildViewController

Page 43: Creating Container View Controllers

- (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

- (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

Demo

Page 46: Creating Container View Controllers

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

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