iPhone viewWillAppear不会触发

时间:2020-03-06 14:42:02  来源:igfitidea点击:

我读过许多关于人们在不正确创建视图层次结构时对" viewWillAppear"存在疑问的帖子。我的问题是我不知道这意味着什么。

如果我创建一个" RootViewController"并在该控制器上调用" addSubView",我希望添加的视图将为" viewWillAppear"事件进行连接。

是否有人有一个复杂的程序化视图层次结构的示例,该层次结构成功地在每个级别上都接收了" viewWillAppear"事件?

苹果的文档状态:

Warning: If the view belonging to a view controller is added to a view hierarchy directly, the view controller will not receive this message. If you insert or add a view to the view hierarchy, and it has a view controller, you should send the associated view controller this message directly. Failing to send the view controller this message will prevent any associated animation from being displayed.

问题在于他们没有描述如何执行此操作。 "直接"是什么意思?我们如何"间接"添加视图?

我对Cocoa和iPhone相当陌生,因此,如果除了基本的Hello World垃圾邮件之外还有苹果的有用示例,那将很好。

解决方案

我一直在使用导航控制器。当我想下降到另一个数据级别或者显示我的自定义视图时,请使用以下命令:

[self.navigationController pushViewController:<view> animated:<BOOL>];

当我这样做时,我确实会触发viewWillAppear函数。我想这算作"间接",因为我自己没有调用实际的addSubView方法。我不知道这是否100%适用于应用程序,因为我无法确定我们是否正在使用导航控制器,但也许它将提供一个线索。

我遇到了同样的问题。只需向视图控制器发送" viewWillAppear"消息,然后再将其添加为子视图即可。 (有一个BOOL参数告诉视图控制器是否正在动画显示。)

[myViewController viewWillAppear:NO];

在节拍器示例中查看RootViewController.m。

(我实际上发现Apple的示例项目很棒。比HelloWorld多了很多;)

我对此不是100%肯定,但是我认为将视图添加到视图层次结构直接意味着在视图控制器的视图上调用-addSubview:(例如,[viewview.view addSubview:anotherViewController.view]而不是将新的视图控制器推入导航控制器的堆栈中。

如果使用导航控制器并设置其委托,则不会调用view {Will,Did} {Appear,Disappear}方法。

我们需要改用导航控制器委托方法:

navigationController:willShowViewController:animated:
navigationController:didShowViewController:animated:

我认为添加子视图并不一定意味着该视图将出现,因此并没有自动调用该类的方法

我只是有同样的问题。在我的应用程序中,我有2个导航控制器,并且在一种情况下推同一个视图控制器,而在另一种情况下不起作用。我的意思是,当在第一个UINavigationController中推入完全相同的视图控制器时,调用了viewWillAppear,但在第二个导航控制器中推入时未调用。

然后我碰到了这篇文章,UINavigationController应该调用viewWillAppear / viewWillDisappear方法

并意识到我的第二个导航控制器确实重新定义了" viewWillAppear"。筛选代码表明我没有打电话

[super viewWillAppear:animated];

我添加了它,它起作用了!

该文档说:

If you override this method, you must call super at some point in your implementation.

我认为它们"直接"的含义是通过与xcode"导航应用程序"模板相同的方式进行连接,该模板将UINavigationController设置为应用程序UIWindow的唯一子视图。

使用该模板是我能够通过在UINavigationController中推送/弹出这些控制器时在对象ViewControllers上调用Will / Did / Appear / Disappear方法的唯一方法。答案中的其他解决方案都没有对我有用,包括在RootController中实现它们并将它们传递给(子级)NavigationController。仅在显示/隐藏顶级VC,我的"登录"和navigationVC而不是导航控制器中的子VC时,才在RootController中调用这些函数(will / did / appear / disappear)。将它们"传递"到Nav VC。

我最终使用UINavigationController的委托功能来查找需要我的应用程序中具有后续功能的特定转换,并且该转换确实可行,但是需要更多的工作才能使消失和出现功能得到"模拟"。

同样,今天经过几个小时不停地解决这个问题,让它正常工作也是一个原则问题。使用自定义RootController和子导航VC的任何工作代码段将不胜感激。

万一这对任何人都有帮助。我有一个类似的问题,我的ViewWillAppear没有在UITableViewController上触发。经过大量的试验,我意识到问题是控制我的UITableView的UINavigationController不在根视图上。一旦我解决了这个问题,它现在就可以像冠军一样工作了。

通过调用[view addSubview:subview],"直接"添加视图。
通过诸如交换子视图的选项卡栏或者导航栏之类的方法"间接"添加视图。

每当我们调用[view addSubview:subviewController.view]时,都应该调用[subviewController viewWillAppear:NO](或者视情况而定为YES)。

当我为游戏中的子屏幕实现自己的自定义根视图管理系统时,我遇到了这个问题。手动添加对viewWillAppear的调用解决了我的问题。

[self.navigationController setDelegate:self];

将委托设置为根视图控制器。

因为没有答案被接受,人们(像我一样)落在这里,所以我给出了自己的变化。虽然我不确定那是最初的问题。当导航控制器作为子视图添加到另一个视图时,我们必须像这样自己调用viewWillAppear / Dissappear等方法:

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

    [subNavCntlr viewWillAppear:animated];
}

- (void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [subNavCntlr viewWillDisappear:animated];
}

只是为了使示例完整。这段代码显示在我创建的ViewController并将其添加到放置在该视图上的视图中的ViewController中。

- (void)viewDidLoad {

    // This is the root View Controller
    rootTable *rootTableController = [[rootTable alloc]
                 initWithStyle:UITableViewStyleGrouped];

    subNavCntlr = [[UINavigationController alloc]   
                  initWithRootViewController:rootTableController];

    [rootTableController release];

    subNavCntlr.view.frame = subNavContainer.bounds;

    [subNavContainer addSubview:subNavCntlr.view];

    [super viewDidLoad];
}

.h看起来像这样

@interface navTestViewController : UIViewController <UINavigationControllerDelegate> {
    IBOutlet UIView *subNavContainer;
    UINavigationController *subNavCntlr;
}

@end

在nib文件中,我有一个视图,在此视图下有一个标签,图像和放置控制器的容器(另一个视图)。这是它的外观。我不得不争一些东西,因为这对客户来说是可行的。

我终于找到了解决该问题的方法!

UINavigationControllerDelegate

我认为要点是将导航控件的委托设置为其所在的viewcontroller,并实现UINavigationControllerDelegate和这两种方法。杰出的!我很激动,终于找到了解决方案!