ios 添加为子视图时未调用 UIViewController viewWillAppear
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18235284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIViewController viewWillAppear not called when adding as subView
提问by Fogmeister
I have a UIViewController
that I am loading from inside another view controller and then adding its view to a UIScrollView
.
我有一个UIViewController
我从另一个视图控制器内部加载然后将它的视图添加到UIScrollView
.
self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;
[self.scrollView addSubview:self.statisticsController.view];
I've put breakpoints in the statistics view controller and viewDidLoad
is being called but viewWillAppear
isn't.
我已经在统计视图控制器中放置了断点并且viewDidLoad
正在被调用但viewWillAppear
不是。
Is it because I'm not pushing it onto the hierarchy or something?
是因为我没有把它推到层次结构上还是什么?
回答by rdelmar
You should add statisticsController
as a child view controller of the controller whose view you're adding it to.
您应该将其添加statisticsController
为要添加到其视图的控制器的子视图控制器。
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.
我不确定这是否会viewDidAppear
被调用,但是您可以didMoveToParentViewController:
在子控制器中覆盖,并且会被调用,因此您可以将您本来要放入的任何代码放入viewDidAppear
其中。
回答by AechoLiu
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.
我又遇到了-viewWillAppear:
不叫问题。谷歌搜索后,我来到了这里。我做了一些测试,并找出的调用顺序-addSubview
和-addChildViewController:
是很重要的。
Case 1.will trigger -viewWillAppear:
of controller, but Case 2,it WON'Tcall -viewWillAppear:
.
情况 1.将触发-viewWillAppear:
控制器,但情况 2,它不会调用-viewWillAppear:
.
Case 1:
情况1:
controller?.willMoveToParentViewController(self)
// Call addSubview first
self.scrollView.addSubview(controller!.view)
self.addChildViewController(controller!)
controller!.didMoveToParentViewController(self)
Case 2:
案例2:
controller?.willMoveToParentViewController(self)
// Call adChildViewController first
self.addChildViewController(controller!)
self.scrollView.addSubview(controller!.view)
controller!.didMoveToParentViewController(self)
回答by Alexander Larionov
By default, appearance callbacks are automatically forwarded to children. It's determined with shouldAutomaticallyForwardAppearanceMethodsproperty. Check value of this propery, if it's NOand 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:
默认情况下,外观回调会自动转发给孩子。它由shouldAutomaticallyForwardAppearanceMethods属性确定。检查此属性格式的值,如果是NO,如果你的孩子的viewController应在容器的外观右中出现,应该与以下容器的控制器生命周期实现方法通知孩子:
- (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.
解决了我的问题!希望它会有所帮助。
回答by bompf
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.
正如另一个答案中提到的,父视图控制器viewWillAppear
在shouldAutomaticallyForwardAppearanceMethods
设置为时可能不会调用等false
。UINavigationController
并且UITabBarController
众所周知这样做。在这种情况下,您需要在视图出现时beginAppearanceTransition(_ isAppearing: Bool, animated: Bool)
使用isAppearing
set调用子视图控制器,true
反之亦然。
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.
不要忘了打电话endAppearanceTransition
时,您的自定义转换已经结束,否则你的孩子视图控制器上viewDidAppear
,并viewDidDisappear
没有叫。
回答by gumbypp
Per Apple (https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html), the correct order of API calls to add a child view controller is:
对于 Apple ( https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html),添加子视图控制器的 API 调用的正确顺序是:
[self addChildViewController:childVC];
[self.view addSubview:childVC.view];
[childVC didMoveToParentViewController:self];
But I still had the problem where viewWillAppear in the child VC was not sporadically getting called. My issue was that there was a race condition that could cause the code above to get executed beforeviewDidAppear in the container view controller was called. Ensuring that viewDidAppear had already been called (or deferring the addition of the child VC until it was) solved it for me.
但是我仍然遇到了问题,即子 VC 中的 viewWillAppear 没有偶尔被调用。我的问题是存在竞争条件,可能导致上面的代码在容器视图控制器中的 viewDidAppear 被调用之前被执行。确保 viewDidAppear 已经被调用(或推迟添加子 VC 直到它被调用)为我解决了这个问题。
回答by Liron
The previous answers are correct, but in case it helps someone - if you override loadView
in the child view controller, then none of the other UIViewController methods get called.
以前的答案是正确的,但如果它对某人有帮助 - 如果您loadView
在子视图控制器中覆盖,则不会调用其他 UIViewController 方法。
Took me some time to realize why my code wasn't running properly, until I realized that I had accidentally overridden loadView
instead of viewDidLoad
.
我花了一些时间才意识到为什么我的代码运行不正常,直到我意识到我不小心覆盖loadView
了viewDidLoad
.
回答by Serg
Check if your parentVC is a UINavigationViewController(or any other container). In this case the shouldAutomaticallyForwardAppearanceMethodsis Falseand the appearance methods are not called.
检查您的父VC 是否为UINavigationViewController(或任何其他容器)。在这种情况下,shouldAutomaticallyForwardAppearanceMethods为False并且不调用外观方法。
回答by YSR fan
I can't understand your questions and your description. My problem was similar to this only.
我无法理解你的问题和你的描述。我的问题仅与此类似。
CustomTabBarController -> CustomUINavigationController -> RootViewcontroller
CustomTabBarController -> CustomUINavigationController -> RootViewcontroller
viewWillAppear of CustomUINavigationController and RootViewController are not getting called unless you switched to another tab and come back.
除非您切换到另一个选项卡并返回,否则不会调用 CustomUINavigationController 和 RootViewController 的 viewWillAppear。
The solution is call super.viewWillAppear(animated: true)
解决方法是调用 super.viewWillAppear(animated: true)
override func viewWillAppear(_ animated: Bool) {
**super.viewWillAppear(true)**
}
I struggled for more than a day for this small mistake.
为了这个小错误,我挣扎了一天多。