ViewDidLoad not called when added to Container View

I have a container view installed in my storyboard file, but I want to embed the view controller programmatically after setting some properties. This is my code in the parent VC viewDidLoad:

_workoutVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"entryTableVC"]; _workoutView = _workoutVC.tableView; [self addChildViewController:_workoutVC]; [_workoutVC.tableView setFrame:_container.bounds]; [_container addSubview:_workoutView]; 

However, viewDidLoad in the child device is not called at any time. When I run the simulator, my container view is empty. I checked in the debugger that none of my properties are nil .

+4
source share
7 answers

The viewDidLoad: method is called when the view property is accessible for the first time. I assume in your case view == tableView . If not, you should configure the loadView method of your child VC.

 - (void)loadView { //create your table view here //... self.view = self.tableView; } 

Then just use the view property instead of tableView .

 _workoutView = _workoutVC.view; 

EDIT:

Full code:

 _workoutVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"entryTableVC"]; _workoutView = _workoutVC.view; [self addChildViewController:_workoutVC]; [_workoutView setFrame:_container.bounds]; [_container addSubview:_workoutView]; 
0
source

If you do not use the built-in segue and add the child view controllers manually, why use the container view at all? Try the following:

 _workoutVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"entryTableVC"]; _workoutView = _workoutVC.tableView; [self addChildViewController:_workoutVC]; [_workoutVC.view setFrame:self.view.frame]; [self.view addSubview:_workoutVC.view]; 
0
source

I had a similar situation. I used the regular UIView in the container controller (unlike the Xcode represented by the "Container View").

The sequence of events that I used:

  ChildViewController *childViewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ChildViewController"]; childViewController.view.frame = self.viewForChildViewController.frame; self.viewForChildViewController = childViewController.view; [self.view addSubview:self.viewForChildViewController]; [self addChildViewController:childViewController]; [childViewController didMoveToParentViewController:self]; 

This is a bit of a dance, but it allows me to programmatically set the child view controller, and also ensures that -viewDidLoad is called on the child view controller. In addition, after that you can set some properties.

0
source

(Swift 2) Since this question has no accepted answer ...

What I ended up with was creating convenience initialization in the child view controller:

 convenience init() { self.init(nibName: "ChildViewController", bundle: nil) //initializing the view Controller form specified NIB file } 

and in parentViewController viewDidLoad () :

 let commentsView = CommentsViewController() self.addChildViewController(commentsView) self.momentsScrollView.addSubview(commentsView.view) commentsView.didMoveToParentViewController(self) 

I used a simple UIView, not a UIContainerView, but it is similar.

0
source

Sorry it's late, but I just ran into this problem. This is one of those obscure issues with InterfaceBuilder, where sometimes it does not create complete information for custom classes, so segue does not find the controller class.

In my case, I had two identical views with built-in TableViewControllers. The first worked, the second - no. When studying the storyboard as source code, I saw that in the second there was no additional information, when I added it, viewDidLoad is called. To fix this

1) Open the storyboard as source code.

2) Search to find customClass for the built-in view controller

 customClass="MyEmbeddedViewController" 

2) Add the following values ​​after it (MyAppProject should be the name of your project, the goal is only the goal).

 customModule="MyAppProject" customModuleProvider="target" 

Your embedded controller should now start viewDidLoad and work fine.

0
source

"I want to embed a view controller programmatically after setting some properties" --- You cannot do this. If you have a container view, you automatically get a view controller built into it, and its viewDidLoad is called right before the parent viewDidLoad controller. If you want to set some properties of the embedded controller, you can do this in prepareForSegue in the parent controller.

-one
source

For everyone who might have the same problem.

I had a similar situation and I decided to just call loadView ().

 let sb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) let controller = sb.instantiateViewControllerWithIdentifier("LoadingView") as! LoadingViewController controller.loadView() 

Then I could access everything inside the view.

-3
source

Source: https://habr.com/ru/post/1494151/


All Articles