Creating Container View Controllers

50,488 views

Published on

Presentation given at 2012 360iDev Conference.

Published in: Technology, Business
3 Comments
39 Likes
Statistics
Notes
  • Thanks for that! You saved my life!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Love it!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Thanks Bob. I had written my own hack to accomplish this, but after upgrading to Xcode 4.5 and iOS 6 it broke. Thanks for providing the correct way to accomplish this!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
50,488
On SlideShare
0
From Embeds
0
Number of Embeds
2,847
Actions
Shares
0
Downloads
353
Comments
3
Likes
39
Embeds 0
No embeds

No notes for slide

Creating Container View Controllers

  1. 1. CreatingContainer View Controllers http://bobmccune.com
  2. 2. About...Bob McCune ‣ MN Developer and Instructor ‣ Owner of TapHarmonic, LLC. ‣ Founded Minnesota CocoaHeads in 2008
  3. 3. AgendaWhat will I learn?‣ View Controller Overview‣ Custom Containers Before iOS 5‣ iOS 5’s View Controller Containment API‣ Custom Container Demo
  4. 4. View Controller Overview
  5. 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. 6. Understanding MVCView Controller: The “C” in MVC Model View Update State Controller User Actions
  7. 7. Understanding MVCView Controller: The “C” in MVC Model View State Changed Controller Update UI
  8. 8. MVC BenefitsCore 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. 9. UIViewController LifecycleStandardized 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. 10. View Controller TypesContainer vs ContentContainer Controllers‣ Manages a hierarchy of child view controllers UITabBarController UINavigationController UISplitViewControllerContent Controllers‣ Manage the individual screens within an app‣ Can be used in multiple presentation contexts‣ Manages a “screenful of content”
  11. 11. Screenful of ContentSeems reasonable...
  12. 12. Screenful of ContentStill reasonable?
  13. 13. UISplitViewControllerWhat’s a screenful?
  14. 14. Why Create Custom Containers?One Screen, Multiple Controllers ‣ Aesthetics ‣ Create a custom application flow
  15. 15.  Pre  -­  iOS  5Custom ContainersThe heartbreaking true story
  16. 16. Custom ContainersFaulty Assumptions Static  Logo
  17. 17. Custom ContainersFaulty Assumptions Static  Logo
  18. 18. Custom ContainersFaulty Assumptions Static  Logo
  19. 19. Custom ContainersFaulty Assumptions can’t! No you Static  Logo
  20. 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. 21. How do you fix it?Ugly OptionsCreate a MonstrosityControllerNot practicalCreate non-UIViewController controllersNot scalableCreate container and forward callbacksIncomplete and ugly
  22. 22. View Controller Containment
  23. 23. Object HierarchiesView vs View Controller View Hierarchy Window Root View NavBar Segmented Tab Bar
  24. 24. Object HierarchiesView vs View Controller View Controller Hierarchy UITabBarController UINavigationController ContentViewController
  25. 25. View Controller ContainmentSimple, but subtleAdding 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. 26. Containment API UsageAdding a Child View Controller [self addChildViewController:controller]; [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; view ParentViewControllerwillMove view ChildViewController
  27. 27. Containment API UsageAdding a Child View Controller [self addChildViewController:controller]; [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; view ParentViewController view ChildViewController
  28. 28. Containment API UsageAdding a Child View Controller [self addChildViewController:controller]; [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self]; view ParentViewControllerdidMove view ChildViewController
  29. 29. Containment API UsageRemoving a Child View Controller [controller willMoveToParentViewController:nil]; [controller.view removeFromSuperview]; [controller removeFromParentViewController]; view ParentViewControllerwillMove view ChildViewController
  30. 30. Containment API UsageRemoving a Child View Controller [controller willMoveToParentViewController:nil]; [controller.view removeFromSuperview]; [controller removeFromParentViewController]; view ParentViewController view ChildViewController
  31. 31. Containment API UsageRemoving a Child View Controller [controller willMoveToParentViewController:nil]; [controller.view removeFromSuperview]; [controller removeFromParentViewController]; view ParentViewControllerdidMove view ChildViewController
  32. 32. View Controller TransitionsSimplifying 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. 33. Cloning UINavigationControllerpushViewController: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. 34. Cloning UINavigationControllerpopViewControllerAnimated:- (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. 35. Disabling Auto ForwardingFine Tuning Containment- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers{ return NO;}• Control timing of appearance and rotation callbacks• Useful override in complex containment scenarios
  36. 36. Avoiding Common Mistakes
  37. 37. Common MistakesSimple API, Common Problems ‣ Outside Callers ‣ Disobedient Children ‣ Meddling Parents
  38. 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. 39. Disobedient ChildrenParents make the rules CustomContainerController OtherViewController ChildViewControllerCustomContainerController- (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. 40. Disobedient ChildrenParents make the rules CustomContainerController OtherViewController ChildViewControllerCustomContainerController- (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. 41. Disobedient ChildrenParents make the rules CustomContainerController OtherViewController ChildViewControllerCustomContainerController- (void)showChildViewController:(UIViewController *)controller { [self addChildViewController:controller]; controller.view.frame = CGRectMake(0, 260, 320, 220); [self.view addSubview:controller.view]; [controller didMoveToParentViewController:self];}
  42. 42. Meddling ParentsLet children be children ParentViewController ChildViewController
  43. 43. Meddling ParentsLet children be children ParentViewController ChildViewControllerParentViewController- (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. 44. Meddling ParentsLet children be children ParentViewController ChildViewControllerChildViewController- (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. 45. Demo
  46. 46. SummaryView Controller Containment FTW! ‣ Simple, but subtle API. Easy to make mistakes. ‣ Need to understand UIViewController internals ‣ Small, but important, enhancements in iOS 6
  47. 47. ResourcesPresentation Materialshttp://www.slideshare.net/bobmccune/https://github.com/tapharmonic/WWDC 2011: Implementing View Controller Containmenthttps://developer.apple.com/videos/wwdc/2011/?id=102WWDC 2012: The Evolution of View Controllers on iOShttps://developer.apple.com/videos/wwdc/2012/?id=236 BobMcCune.com @bobmccune

×