10

在我的主 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];    
4

8 回答 8

33

就我而言,没有调用 viewDidAppear,因为我在 viewWillAppear 方法中犯了不必要的错误。

-(void)viewWillAppear:(BOOL)animated {
    [super viewdidAppear:animated]; // this prevented my viewDidAppear method to be called
}
于 2016-09-08T14:14:13.940 回答
14

我可以重现子控制器不接收外观方法的问题的唯一方法是容器视图控制器是否执行以下操作(我确定您没有这样做):

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return NO;
}

也许您可以尝试显式启用此功能:

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return YES;
}

但是我的子视图控制器肯定会viewWillAppear接到电话(如果我明确地automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers或者我完全忽略了这个。

更新:

好的,看看你原来的问题下的评论,问题似乎是有问题的子控制器(B)本身就是一个容器视图控制器(这是完全可以接受的)呈现另一个子控制器(C)。这个控制器 B 自己的子控制器 C 正在被移除,你想知道为什么你没有得到容器viewWillAppear控制器viewDidAppearB应该移除孩子,而不是孩子自己移除,当容器移除孩子时,它不会收到外观方法)。

如果我误解了情况,请告诉我。

于 2012-07-18T04:02:30.367 回答
9

@Rob 在 Swift 4 中的回答(这对我添加 achildViewController到 a 的情况有所帮助UITabBarController

override var shouldAutomaticallyForwardAppearanceMethods: Bool {
    return true
}
于 2017-10-04T15:37:17.610 回答
2

Another case where this will not be called at launch time (yet may be called on when you return to the view) will be is if you have subclassed UINavigationController and your subclass overrides

-(void)viewDidAppear:(BOOL)animated

but fails to call [super viewDidAppear:animated];

于 2020-04-07T22:14:16.697 回答
1

有同样的问题我的容器视图retain控制器通过 a 做了一个子视图控制器property没有将子视图控制器添加到它的childViewControllers array.

我的解决方案是在容器视图控制器中添加这行代码

[self addChildViewController: childViewController];

之后UIKit开始按预期将外观方法转发给我的子视图控制器

我还将属性属性从更改strongweak只是为了美观

于 2016-02-16T16:38:30.893 回答
1

将我的代码更新到 13.0 时,我丢失了 viewDidAppear 调用。

在 Objective-c 中,我的解决方案是将以下覆盖全部添加到父主视图控制器。

这允许再次调用 ViewDidAppear 调用......就像在以前的 IOS(12 和更早版本)中所做的那样。

@implementation MasterViewController

//....一些方法

  • (BOOL) shouldAutomaticallyForwardAppearanceMethods { 返回 YES; }

// ...一些方法

@结尾

于 2019-10-04T17:57:19.537 回答
0

我的问题是我正在更改 UITabBarController (selectedIndex = x) 中的选项卡,然后弄乱了该选项卡中的子视图控制器。问题是它需要以相反的方式完成:首先在其他选项卡中弄乱子视图控制器,然后通过设置 selectedIndex 来更改选项卡。在此更改方法 viewWillAppear/viewDidAppear 开始被正确调用之后。

于 2014-04-08T00:57:46.287 回答
-10

使用 presentModalViewController 或 segues 或 pushViewController 呈现视图控制器应该可以修复它。

或者,如果由于某种原因您想在没有内置方法的情况下显示视图,则应该在您自己的代码中手动调用这些方法。像这样的东西:

[self addChildViewController:controller];
BOOL animated = NO;
[controller viewWillAppear:animated];
[self.view insertSubview:controller.view atIndex:0];
[controller viewDidAppear:animated];
[controller didMoveToParentViewController:self];   
于 2012-07-18T00:53:43.507 回答