UIViewController viewWillAppear not called when adding as subView
As mentioned in another answer, the parent view controller might not call viewWillAppear
etc. when shouldAutomaticallyForwardAppearanceMethods
is set to false
. UINavigationController
and UITabBarController
are known to do that. In this case, you need to call beginAppearanceTransition(_ isAppearing: Bool, animated: Bool)
on the child view controller with isAppearing
set to true
when the view appears and vice versa.
You have to place these calls at appropriate places in your code, normally when you add and remove your child view controller.
Don't forget to call endAppearanceTransition
on your child view controller when your custom transition has ended, otherwise viewDidAppear
and viewDidDisappear
are not called.
I encounter -viewWillAppear:
not called problem again. After googling, I came here. I did some tests, and find out that the calling order of -addSubview
and -addChildViewController:
is important.
Case 1. will trigger -viewWillAppear:
of controller, but Case 2, it WON'T call -viewWillAppear:
.
Case 1:
controller?.willMoveToParentViewController(self)
// Call addSubview first
self.scrollView.addSubview(controller!.view)
self.addChildViewController(controller!)
controller!.didMoveToParentViewController(self)
Case 2:
controller?.willMoveToParentViewController(self)
// Call adChildViewController first
self.addChildViewController(controller!)
self.scrollView.addSubview(controller!.view)
controller!.didMoveToParentViewController(self)
By default, appearance callbacks are automatically forwarded to children. It's determined with shouldAutomaticallyForwardAppearanceMethods property. Check value of this propery, if it's NO and if your child viewController should appear right on container's appearance, you should notify child with following methods in container's controller life-cycle implementation:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for (UIViewController *child in self.childViewControllers) {
[child beginAppearanceTransition:YES animated:animated];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.child endAppearanceTransition];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
for (UIViewController *child in self.childViewControllers) {
[child beginAppearanceTransition:NO animated:animated];
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.child endAppearanceTransition];
}
Customizing Appearance and Rotation Callback Behavior
Fixed my problem! Hope it would be helpful.
You should add statisticsController
as a child view controller of the controller whose view you're adding it to.
self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;
[self.scrollView addSubview:self.statisticsController.view];
[self addChildViewController:self.statisticsController];
[self.statisticsController didMoveToParentViewController:self];
I'm not sure this will make viewDidAppear
get called, but you can override didMoveToParentViewController:
in the child controller, and that will be called, so you can put any code that you would have put in viewDidAppear
in there.