0

I'm looking to have a custom timer object in my navigation bar that displays the time and responds to messages (start,stop,etc.). I've successfully added a child view controller to my UINavigationBar using the following code (placed in viewDidLoad of a UIViewController):

self.timerViewController=[[TimerViewController alloc] init];
self.timerViewController.delegate=self;
[self.timerViewController.view setFrame:CGRectMake(935,
                                                   -20,
                                                   self.timerViewController.view.frame.size.width,
                                                   self.timerViewController.view.frame.size.height)];
[self.navigationController addChildViewController:self.timerViewController];
[self.navigationController.navigationBar addSubview:self.timerViewController.view];

My question is whether this approach could be problematic at all? E.g., is it OK to have a child view controller of a navigationController? (I originally had tried just using the right bar button item with a custom view, but there was a gap between the item and the right side of the screen as described in this question.)

Community
  • 1
  • 1
Rogare
  • 3,234
  • 3
  • 27
  • 50
  • It is _never_ okay to manually add a view controller's view as a subview manually to another view controller's view. You are totally subverting the behavior of the navigation controller. – matt Apr 13 '15 at 22:25
  • @matt Thanks for the comment! So, when setting up a childViewController (for any view controller, not just the navigation controller), what's the better approach? – Rogare Apr 13 '15 at 23:17
  • I don't see why you need a child view controller at all. If you want to add a subview, add it. But if you want to add a child view controller to a navigation controller, there is only one legal way to do that: push it (or otherwise add it to the stack), and make no attempt to interfere with its frame or other behavior. (It seems as if you don't really understand about view controllers and their hierarchy. You might want to read my book, starting here: http://www.apeth.com/iOSBook/ch19.html#_the_view_controller_hierarchy – matt Apr 14 '15 at 00:35
  • Hi @matt, thanks for the link, though there may be some misunderstanding about the goal, as it's not to push a new view onto the stack. It's simply to have an area of the navigation bar be a custom view controller (http://stackoverflow.com/questions/29582368/to-use-a-uiview-or-uiviewcontroller-for-timer-object), but without the right margin that occurs when using a right bar button item (http://stackoverflow.com/questions/18914812/how-to-edit-empty-spaces-of-left-right-uibarbuttonitem-in-uinavigationbar-ios). I'll edit the question to clarify. – Rogare Apr 14 '15 at 14:41
  • I don't think so. I think your goal is to have an area be a custom _view_. This has nothing to do with view controllers. That's my point (indeed, see my previous comment). – matt Apr 14 '15 at 14:43

1 Answers1

3

As matt mentioned, adding other view controller view as a subview is a bad approach. You should consider using the child view controller property. I've added an example on to add (and remove) a view controller, to a navigation controller:

- (void)addToNavigationControllerViewController:(UIViewController *)controller
{
    [controller willMoveToParentViewController:self.navigationController];
    [self.navigationController addChildViewController:controller];
    controller.view.frame = self.navigationController.view.bounds;
    [self.navigationController.view addSubview:controller.view];
    [controller didMoveToParentViewController:self.navigationController];
}

- (void)removeFromParentViewControllerChildViewController:(UIViewController *)controller
{
    // dismissing a View Controller from it's Parent View Controller
    [controller willMoveToParentViewController:nil];
    [controller.view removeFromSuperview];
    [controller removeFromParentViewController];
    [controller didMoveToParentViewController:nil];
    controller = nil;
}
Asaf
  • 2,158
  • 2
  • 25
  • 40