0
votes

I'm facing an odd problem concerning pushing a UIViewController into a UINavigationController. CustomTableViewController is a subclass of UITableViewController

CustomTableViewController* vc = [[CustomTableViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:vc];
[self.view addSubview:navVC.view];

For some reason, the Navigation Controller is loaded and visible on screen but viewDidLoad is never called on CustomTableViewController.

Manually pushing the VC afterwards also does not work (still not loading the vc's view)

  • [navVC pushViewController:vc animated:YES];

However, the following methods DO call viewDidLoad on vc:

  1. [self.view addSubview:vc.view];
  2. [self presentViewController:navVC animated:YES completion:nil];
  3. [self presentViewController:vc animated:YES completion:nil];

So I tend to believe that there is nothing wrong with the View Controller nor the Navigation Controller. However, I have no clue why the view is not being loaded. Manually forcing [vc view] will load the view but then the other view lifecycle methods are not called.

There is also nothing wrong with CustomTableViewController, as using UITableViewController itself also doesn't work.

Any ideas?

2
Why are you adding the navVC view as a subView of self.view? I think you're not using it correctly. But yes, if what you are doing is correct (which I don't think it is) then @Bobj-C answer below will work. - Fogmeister
I have a UITabBarController with a few dynamically added ViewControllers. Every ViewController holds one (in the future multiple) dynamic form(s), which can be a UITableViewController (with its own logic). This UITableViewController uses a UINavigationController for the add / edit logic behind it. - Glenn
It sounds like you should probably be putting your navVC into the viewControllers array on your UITabBarController - Paulw11
If you want to have navigation controllers from a tab bar controller then you should have it as... UITabBarController - UINavigationController - ContentControllers. The Tab Bar then swaps between the NavigationControllers. - Fogmeister
Not really, because in the future, it's possible that the top half of my VC is a TableView with Navigation Controller, but the bottom half is another form type. - Glenn

2 Answers

2
votes

You need to add it as child view controller

    [childController willMoveToParentViewController:rootViewController];
    [rootViewController addChildViewController:childController];
    [rootViewController.view addSubview:childController.view];
    [childController didMoveToParentViewController:rootViewController];

Hope this works

2
votes

I suspect you're getting issues because it seems you are trying to make a custom container view controller.

Read up on Apple's guide on custom container view controllers.

From the guide, here are some example methods to add and remove child view controllers:

Swift 3.0:

func display(contentController content: UIViewController) {
    addChildViewController(content)

    // Here, frameForContentController is just some function you define
    // that calculates and returns the frame of the content controller's view.
    content.view.frame = frameForContentController()

    view.addSubview(content.view)
    content.didMove(toParentViewController: self)
}

func hide(contentController content: UIViewController) {
    content.willMove(toParentViewController: nil)
    content.view.removeFromSuperview()
    content.removeFromParentViewController()
}

Objective-C:

- (void)displayContentController:(UIViewController *)content
{
   [self addChildViewController:content];

   // Here, [self frameForContentController] is just some method you define
   // that calculates and returns the frame of the content controller's view.
   content.view.frame = [self frameForContentController];

   [self.view addSubview:content.view];
   [content didMoveToParentViewController:self];
}

- (void)hideContentController:(UIViewController *)content
{
   [content willMoveToParentViewController:nil];
   [content.view removeFromSuperview];
   [content removeFromParentViewController];
}