UIViewController:viewWillAppear被调用,viewDidAppear没有被调用

18

在UIViewController的子类中,我有以下方法:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // do something
    myTextField.text = @"Default";
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // do something
    [myTextField selectAll:self];
    [myTextField becomeFirstResponder];
}

- (void)viewDidLoad {
    [super viewDidLoad];    
    // do something
    myTextField.delegate = self;
}

使用Interface Builder创建了NIB。相应的视图控制器对象通过pushViewController推送导航控制器。

预期的行为是在文本字段中显示默认文本条目,选择整个文本并将文本字段设置为第一响应者。[编辑:我注意到选择全部和使第一响应者没有意义,因为选择会消失;不过,我想知道为什么下面描述的方法会像这样表现。]

然而,虽然viewDidLoad和viewWillAppear方法被调用,但viewDidAppear方法未被调用。有人能告诉我为什么吗?我在网上和这里找到的大多数问题都涉及到viewWillAppear/viewDidAppear都无法工作;我还了解到,在子视图或以编程方式创建的视图中,这些方法不会被调用;但在此情况下不适用,我也想知道为什么其中一个“生命周期”方法被调用而另一个没有。

有任何想法吗?谢谢!

5个回答

28

我遇到了这个问题: viewWillAppear 被调用了,但是 viewDidAppear 没有被调用!

最后我发现这是因为我有一个 tabBarController ,我重载了它自己的 viewDidAppear ,但是忘记了加上 [super viewDidAppear:animated]; 这一行代码。

这导致每个选项卡中的所有视图控制器都出了问题!把这一行代码加回去就解决了其他视图控制器的问题。

希望这能帮助到某些人!


1
这正是我在我的 Swift 项目中遇到的情况。谢谢! - Kilo Loco
这正是我在我的Swift项目中遇到的情况。谢谢! - Moosa Baloch

2

有一种情况下,viewWillAppear会被调用,但viewDidAppear不会被调用。

假设您有两个viewControllers,并且从第一个控制器推到第二个控制器。然后,使用滑动手势,您想返回到第一个控制器,那么两个控制器将同时显示,并且此时将从第一个控制器调用viewWillAppear

这样,您就没有完成滑动操作,停留在第二个控制器上,因此viewDidAppear将不会从第一个控制器调用。


1
我遇到了同样的问题。
我复制/粘贴了viewDidAppear以创建viewWillAppear,但忘记更改super.viewDidAppear()的调用。这似乎阻止了viewDidAppear的调用。
听起来你的代码中某处缺少或混淆了对超类的调用。

0

viewDidAppear: 的调用应该始终在 viewWillAppear: 之后,除非你正在做一些自定义操作,而你说你没有。我不知道为什么它不起作用,但是这里有一些想法:

你是否在 UITextFieldDelegate 的一个委托方法中做了一些奇怪的事情?虽然它不太可能影响到 viewDidAppear: 的调用,但它可能是罪魁祸首。

在推出视图之前,你是否将大量内容加载到内存中?如果在 viewWillAppear:viewDidAppear: 之间收到内存警告,我不确定会发生什么。

你尝试过进行清理吗?有时候这样可以帮助解决问题。

在像这样应该工作的情况下,我通常会创建一个新类,并逐个引入功能,以查看是否可以通过这种方式使其正常工作。我在一个新的基于导航的项目中尝试了你的代码,其中添加了一个新的 UIViewController,并将代码从问题中粘贴进去,结果按预期工作。


不应该有内存问题,至少不会调用didReceiveMemoryWarning。清除所有目标也没有帮助。所以我按照你的建议,在一个新项目中逐步“复制”了这个类。然后它就可以工作了。 :-/ 我已经添加了我在原始类中重写的所有方法,在一个项目中它可以工作,在另一个项目中它不能工作。在两种情况下,视图都是通过navcontroller的pushViewController显示的。唯一的区别是,在测试项目中只有一个navcontroller,在我的项目中有三个(rootcontroller是一个tabbarcontroller)。 - Sven Tiffe
@sven - 我想要改变导航栏的标题视图。当viewWillAppear被触发时,似乎该视图尚未被推送到导航栏。 - OmniBus

0
这可能是因为您在viewDidLoadviewWillAppear中向父VC添加了一个子视图控制器。子视图的出现阻止了对viewDidAppear的调用。
这是一件疯狂的事情,我之所以知道是因为这是我的代码中的一个错误。我本意是将子VC添加到此VC而不是父VC。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接