问题
I have a container view set up in my storyboard file but I want to embed the view controller programatically after setting some properties. This is my code in the parent VC's 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 is not called at any time. When I run the simulator my container view is blank. I've checked in the debugger that none of my properties are nil
.
回答1:
If you aren't using an embed segue and are adding child view controllers manually, why use a container view at all? Try this:
_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];
回答2:
The viewDidLoad:
method is called when the view
property is accessed for the first time. I assume that in your case view
== tableView
. If not, you have to adjust the loadView
method of your child VC.
- (void)loadView {
//create your table view here
//...
self.view = self.tableView;
}
Then just use view
property instead of tableView
.
_workoutView = _workoutVC.view;
EDIT:
The full code would be:
_workoutVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"entryTableVC"];
_workoutView = _workoutVC.view;
[self addChildViewController:_workoutVC];
[_workoutView setFrame:_container.bounds];
[_container addSubview:_workoutView];
回答3:
(Swift 2) Since this question doesn't have an accepted answer...
What I ended up doing is create a convenience init at the child view controller:
convenience init() {
self.init(nibName: "ChildViewController", bundle: nil)
//initializing the view Controller form specified NIB file
}
and in the parentViewController's viewDidLoad():
let commentsView = CommentsViewController()
self.addChildViewController(commentsView)
self.momentsScrollView.addSubview(commentsView.view)
commentsView.didMoveToParentViewController(self)
I used a simple UIView not UIContainerView, but it's similar.
回答4:
I had a similar situation. I used a normal UIView in the container view controller (as opposed to the Xcode provided "Container View").
The sequence of events that I used is:
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];
It's a bit of a dance but it allows me to programmatically set the child view controller and also insures that -viewDidLoad is called on the child view controller. Also, you should be able to set some properties after this.
回答5:
Sorry this is late but I just ran into this problem. It's one of those obscure problems with InterfaceBuilder, where occasionally it doesn't create complete information for custom classes, so the segue isn't finding the controller class.
In my case I had two identical views with embedded TableViewControllers. The first worked, the second didn't. When examining the Storyboard as source code I saw that the second was missing some extra information, when I added it, viewDidLoad was called. To fix this
1) Open your storyboard as source code.
2) Search to find the customClass for your embedded view controller
customClass="MyEmbeddedViewController"
2) Add the following values after it (MyAppProject should be the name of your project, target is just target).
customModule="MyAppProject" customModuleProvider="target"
Your embedded controller should now trigger viewDidLoad and work normally.
回答6:
"I want to embed the view controller programatically after setting some properties" --- You can't do that. If you have a container view, you automatically get a view controller embedded in it, and its viewDidLoad is called right before the parent controller's viewDidLoad. If you want to set some properties of the embedded controller, you can do that in prepareForSegue in the parent controller.
回答7:
To anyone that might still have the same problem.
I had a similar situation and solved it by just calling loadView().
let sb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let controller = sb.instantiateViewControllerWithIdentifier("LoadingView") as! LoadingViewController
controller.loadView()
I could then access everything inside the view.
来源:https://stackoverflow.com/questions/17935110/viewdidload-not-called-when-adding-to-container-view