在我的主 UIViewController 中,我添加一个主屏幕视图控制器作为子视图:
UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController:vc];
controller.navigationBarHidden = YES;
controller.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
[self addChildViewController:controller];
[self.view insertSubview:controller.view atIndex:0];
[controller didMoveToParentViewController:self];
问题是 viewDidAppear 和 viewWillAppear 只被调用一次,就像 viewDidLoad 一样。为什么是这样?我怎样才能做到这一点?
基本上在 vc 中我没有得到 viewDidAppear 或 viewWillAppear。
我也尝试添加 UIViewController 而不使用导航控制器,但它仍然不起作用:
vc.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
[self addChildViewController:vc];
[self.view insertSubview:vc.view atIndex:0];
[vc didMoveToParentViewController:self];
在我的例子中,viewDidAppear没有被调用,因为我在viewWillAppear方法中犯了不必要的错误。
-(void)viewWillAppear:(BOOL)animated {
[super viewdidAppear:animated]; // this prevented my viewDidAppear method to be called
}
我可以重现子控制器未接收外观方法问题的唯一方法是容器视图控制器执行以下操作(我确定您没有这样做):
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
return NO;
}
也许您可以尝试显式启用此功能:
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
return YES;
}
但是我的子视图控制器肯定会收到
viewWillAppear
调用(如果我明确 automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
或者我完全忽略它。
更新:
好吧,看看你原来问题下的评论,问题似乎是有问题的子控制器(B)本身就是一个容器视图控制器(这是完全可以接受的),呈现另一个子控制器(C)。并且此控制器 B 自己的子控制器 C 正在被删除,您想知道为什么容器控制器 B 没有获得
viewWillAppear
或 viewDidAppear
。当其子控制器被删除时,容器控制器确实 not 获得这些外观方法(或者,更准确地说,由于容器应该删除子项,而不是子项删除自身,因此当容器删除子项时,它不会收到外观方法)。
如果我误解了情况,请告诉我。
@Rob 在 Swift 4 中的回答(这对我的案例有帮助,我在
childViewController
中添加了 UITabBarController
)
override var shouldAutomaticallyForwardAppearanceMethods: Bool {
return true
}
另一种情况是,如果您已经子类化了
UINavigationController
并且您的子类覆盖了,则在启动时不会调用此方法(但可能会在您返回视图时调用)
-(void)viewDidAppear:(BOOL)animated
但无法拨打电话
[super viewDidAppear:animated];
也有同样的问题 我的容器视图控制器通过
retain
做了 property
子视图控制器,但是 没有将子视图控制器添加到其 childViewControllers
array
。
我的解决方案是在容器视图控制器中添加这行代码
[self addChildViewController: childViewController];
之后
UIKit
开始按照预期将外观方法转发到我的子视图控制器
我还把property属性从
strong
改成了weak
只是为了美观
将代码更新到 13.0 时,我丢失了 viewDidAppear 调用。
在 Objective-c 中,我的解决方案是将以下覆盖全部添加到父主视图控制器中。
这允许再次调用 ViewDidAppear...就像在以前的 IOS(12 及更早版本)版本中一样。
@实现MasterViewController
//....一些方法
// ...一些方法
我的问题是我正在更改 UITabBarController (selectedIndex = x) 中的选项卡,然后弄乱该选项卡中的子视图控制器。问题是,它需要以相反的方式完成:首先弄乱其他选项卡中的子视图控制器,然后通过设置 selectedIndex 来更改选项卡。在此更改后,viewWillAppear/viewDidAppear 方法开始被正确调用。
这是以编程方式呈现 viewController 的另一种情况;
viewWillAppear
或 viewDidAppear
不会被调用,使用 .overCurrentContext
两个函数都会被触发.currentContext
或者,如果出于某种原因您想在没有内置方法的情况下呈现视图,则应该在您自己的代码中手动调用这些方法。像这样的东西:
let destinationVC = TestAppearanceViewController()
destinationVC.modalTransitionStyle = .coverVertical
destinationVC.modalPresentationStyle = .currentContext // Remove behind view controller and force presenter view controller calls both functions
vc.present(destinationVC, animated: true)