iOS presentViewController 不调用 viewDidLoad

Posted

技术标签:

【中文标题】iOS presentViewController 不调用 viewDidLoad【英文标题】:iOS presentViewController doesn't invoke viewDidLoad 【发布时间】:2014-07-28 02:34:56 【问题描述】:

我正在实现自己的“后退”按钮。其中onClick,在被关闭的ViewController(VC)中执行如下代码:

    关闭当前 VC (VC#1) 从我的自定义 navigationStack 中弹出当前 VC (VC#1) 从navigationStack 获取最后一个 VC (VC#2),并使用它呈现它

presentViewController

后面的工作在视觉上是有效的——即当前的VC 消失了,之前的VC 出现了。但是,不会调用viewDidLoad 方法。所以屏幕不会使用来自viewDidLoad 的数据更新。

 [self dismissCurrentViewController:self completion:^
    [TWStatus dismiss];
    FHBaseViewController *vcToDisplay = [[FHDataManager sharedInstance] popNavigationStack];
    [vcToDisplay.homeVC presentViewController:vcToDisplay animated:NO completion: ^ ];
];

问题:

    我的印象是viewDidLoad 总是在使用presentViuewController 时被调用?? 我使用 VC#2 中的 viewDidLoad 调用的方法“构建”屏幕。 ios如何显示屏幕而不进入viewDidLoad

顺便说一句,我没有使用故事板。任何帮助表示赞赏!

【问题讨论】:

如果我的答案解决了,请告诉我! 感谢@Kanan Vora 的代码编辑! 不客气!!! :-) 【参考方案1】:

我的猜测是 viewWillAppear 正在被调用,但 viewDidLoad 没有被调用,至少在你期望的时候不会。 viewDidLoad 应该被调用一次,但根据您管理视图控制器的方式,viewDidLoad 可能不会在每次视图出现时都被触发(加载后发生)。

The completion handler is called after the viewDidAppear: method is called on the presented view controller. 来自presentViewController doc

因此,在调用 super 时将其放入您的代码中并设置断点,并验证在此转换发生时它是否被调用。

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];

编辑:既然您验证了viewWillAppear 被调用,那么我想说这取决于您如何管理视图控制器生命周期。即使使用标准的UINavigationController,当由于在导航堆栈上弹出项目而显示视图时,也不会调用viewDidLoad。如果您坚决不使用UINavigationController,我会将您的逻辑移至viewWillAppear

【讨论】:

谢谢@mckeejm。 viewWillAppear 有效。我发现presentingViewController 不会调用viewDidLoad(因为它已经在内存中了)。在创建对象时(通过 init、new 或 copy)创建 viewDidLoad。我已将代码移至 viewWillAppear :D 次要问题,仅在视图控制器上执行 [[alloc] init] 不会导致调用 viewDidLoad。我在测试中经常看到这种情况。我们通常在 Cedar 测试框架viewController.view should_not be_nil 中使用一个技巧,它会导致视图被延迟实例化并触发 viewDidLoad。但是,如果您使用的是initWithNibName,则应该为您调用viewDidload 嘿@mckeejm。你能解释一下viewController.view should_not be_nil是什么意思吗?顺便说一句,我通过代码运行所有视觉效果,没有 nib 或界面生成器。谢谢! 有点题外话,但它与特定的测试框架github.com/pivotal/cedar有关。这是您可以在该测试框架中使用的快捷方式来触发这些事件以用于单元测试。我想我更想说的是,一个普通的[[alloc] init] 样式初始化程序不一定会膨胀控制器的view 属性。当您使用[[alloc] initWithNibName] 时,它会尝试自动膨胀view 属性。 因为你没有使用笔尖,但我的评论并不相关【参考方案2】:

当我务实地制作后退按钮时,我使用:

[self.navigationController popViewControllerAnimated:YES];

这将调用 viewDidLoad 方法。使用它而不是您当前的代码。

【讨论】:

这对我不起作用。因为我不使用导航控制器来加载我的视图:( 哦,好吧,如果你这样做了,那就行了。我会看看 mckeejm 的答案,这似乎应该有效。 想在上周(此答案后 6.5 年)获得反对票后发表评论。这个答案是不正确的。 viewDidLoad 在弹回视图控制器时不会被调用。 viewWillAppear 在视图控制器出现时被调用,而viewDidLoad 仅在视图控制器第一次加载时被调用。

以上是关于iOS presentViewController 不调用 viewDidLoad的主要内容,如果未能解决你的问题,请参考以下文章

PresentViewController 在 iOS 中隐藏导航栏

PresentViewController iOS 上的 PushView

如何使用 presentViewController 呈现 iOS 键盘扩展

PresentViewController 与 ModalPresentationStyle “UIModalPresentationFormSheet” IOS 8

iOS presentViewController 方法引起的问题

在 iOS 上,presentViewController 会导致溢出(如堆栈溢出)吗?