iPhone的viewWillAppear不开火

我已经阅读了许多有关viewWillAppear问题的人的post,当你没有创build你的视图层次结构恰到好处。 我的问题是我无法弄清楚这是什么意思。

如果我创build一个RootViewController并在该控制器上调用addSubView ,我期望添加的视图被连接到viewWillAppear事件。

有没有人有一个复杂的程序化视图层次的例子,成功地接收每个级别的viewWillAppear事件?

苹果的文件状态:

警告:如果属于视图控制器的视图直接添加到视图层次结构中,视图控制器将不会收到此消息。 如果向视图层次结构中插入或添加视图,并且它具有视图控制器,则应该直接将关联的视图控制器发送此消息。 无法发送视图控制器此消息将阻止显示任何关联的animation。

问题是他们没有描述如何做到这一点。 “直接”是什么意思? 你如何“间接”添加视图?

我对Cocoa和iPhone相当陌生,所以如果除了基本的Hello World废话之外还有其他有用的例子,那将是非常好的。

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

您需要使用导航控制器委托方法:

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

我遇到了同样的问题。 只要将viewWillAppear消息发送到您的视图控制器,然后将其添加为子视图。 (有一个BOOL参数告诉视图控制器是否被animation显示或不显示。)

 [myViewController viewWillAppear:NO]; 

看节拍器例子中的RootViewController.m。

(实际上我发现苹果的例子很棒,比HelloWorld好多了;)

我终于find了这个工作的解决scheme!

UINavigationControllerDelegate

我认为它的要点是设置你的导航控制委托给它所在的视图控制器,并实现UINavigationControllerDelegate ,这是两种方法。 辉煌! 我很激动,我终于find了解决scheme!

我只是有同样的问题。 在我的应用程序中,我有2个导航控制器,并推动相同的视图控制器在其中每一个工作,而不是在另一个。 我的意思是,当推动在第一个UINavigationController完全相同的视图控制器, viewWillAppear被调用,但没有推入第二个导航控制器时。

然后我碰到这个post, UINavigationController应该调用viewWillAppear / viewWillDisappear方法

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

 [super viewWillAppear:animated]; 

我加了它,它的工作!

该文件说:

如果您重写此方法,则必须在实现中的某个时刻调用super。

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

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

当我这样做,我得到viewWillAppear函数来触发。 我认为这符合“间接”,因为我不是自己调用实际的addSubView方法。 我不知道这是否是100%适用于您的应用程序,因为我不能告诉你是否使用导航控制器,但也许它会提供一个线索。

首先,如Apple文档中所述,选项卡栏应位于根级,即添加到窗口。 这是正确的行为的关键。

其次,你可以使用UITabBarDelegate / UINavigationBarDelegate手动转发通知,但我发现为了让整个视图调用的层次结构正常工作,我所要做的就是手动调用

 [tabBarController viewWillAppear:NO]; [tabBarController viewDidAppear:NO]; 

 [navBarController viewWillAppear:NO]; [navBarController viewDidAppear:NO]; 

在设置相应控制器上的视图控制器(分配后)之前,只需一次。 从那时起,它在子视图控制器上正确地调用了这些方法。

我的层次是这样的:

 window UITabBarController (subclass of) UIViewController (subclass of) // <-- manually calls [navController viewWill/DidAppear UINavigationController (subclass of) UIViewController (subclass of) // <-- still receives viewWill/Did..etc all the way down from a tab switch at the top of the chain without needing to use ANY delegate methods 

只要在选项卡/导航控制器上首先调用上述方法,确保所有事件都正确转发。 它阻止了我需要从UINavigationBarDelegate / UITabBarControllerDelegate方法手动调用它们。

旁注:奇怪的是,当它不工作,私人方法

 - (void)transitionFromViewController:(UIViewController*)aFromViewController toViewController:(UIViewController*)aToViewController 

..你可以从一个工作实现的调用堆栈中看到,通常会调用viewWill/Did..方法,但是直到我执行上述操作(即使它被调用)。

我认为这是非常重要的, UITabBarController是在窗口级别,但文件似乎支持这一点。

希望是明确的(ish),很乐意回答更多的问题。

由于没有答案被接受,人们(像我一样)降落在这里,我给我的变化。 虽然我不确定这是否是原来的问题。 当导航控制器作为子视图添加到另一个视图时,您必须像这样调用viewWillAppear / Dissappear等方法:

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

只是为了使例子​​完整。 这段代码出现在我创build的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 

在笔尖文件中,我有视图,在这个视图下面我有一个标签图像和容器(另一个视图),我把控制器放在里面。 我不得不争取一些东西,因为这是一个客户的工作。

替代文字

通过调用[view addSubview:subview]直接添加[view addSubview:subview] 。 视图是通过交换子视图的选项卡栏或导航栏等方法“间接”添加的。

任何时候你调用[view addSubview:subviewController.view] ,你应该调用[subviewController viewWillAppear:NO] (或者你的情况可能是YES)。

当我在游戏中为子屏幕实现我自己的自定义根视图pipe理系统时,我遇到了这个问题。 手动添加呼叫viewWillAppear治愈了我的问题。

正确的方法是使用UIViewController containment api。

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. UIViewController *viewController = ...; [self addChildViewController:viewController]; [self.view addSubview:viewController.view]; [viewController didMoveToParentViewController:self]; } 

我使用这个代码推和popup视图控制器:

推:

 [self.navigationController pushViewController:detaiViewController animated:YES]; [detailNewsViewController viewWillAppear:YES]; 

stream行:

 [[self.navigationController popViewControllerAnimated:YES] viewWillAppear:YES]; 

..它对我来说工作得很好。

一个非常普遍的错误如下。 你有一个视图, UIView* a ,另一个是UIView* b 。 您将b添加到a作为子视图。 如果你尝试在b中调用viewWillAppear,它将永远不会被触发,因为它是a的子视图

我不是100%确定,但我认为直接添加一个视图层次意味着调用-addSubview:在视图控制器的视图(例如, [viewController.view addSubview:anotherViewController.view] ),而不是新的视图控制器到导航控制器的堆栈上。

我认为添加一个子视图并不一定意味着视图会出现,所以不会自动调用类的方法,它会

我认为他们的意思是“直接”是通过挂钩的东西,就像xcode“导航应用程序”模板所做的一样,它将UINavigationController设置为应用程序UIWindow的唯一子视图。

使用该模板是唯一能够在UINavigationController中的这些控制器的推/拉对象上获得在对象ViewController上调用的Will / Did / Appear / Disappear方法的唯一方法。 这里的答案没有任何解决scheme在我这里工作,包括在RootController中实现它们,并将它们传递给(子)NavigationController。 在显示/隐藏顶层VC(我的“login”和导航VCs,而不是导航控制器中的子VC)时,只会在我的RootController中调用这些function(将/出现/消失),所以我没有机会“通过他们”到导航VC。

我结束了使用UINavigationController的委托function来寻找需要在我的应用程序中的后续function的特定转换,并且工作,但它需要更多的工作,以便消失和出现function“模拟”。

在今天这个问题几个小时之后,我的头反了这个问题,这也是一个原则性的问题。 任何使用自定义的RootController和子导航VC的工作代码片段将非常感激。

如果这有助于任何人。 我有一个类似的问题,我的ViewWillAppear没有触发UITableViewController 。 在玩了很多游戏之后,我意识到问题是控制我的UITableViewUINavigationController不在根视图上。 一旦我解决这个问题,它现在像一个冠军。

我自己也遇到了这个问题,我花了3个整小时(其中2个使用Google)来解决这个问题。

事实certificate,只是简单地从设备/模拟器中删除应用程序,清理,然后再次运行

希望有所帮助

 [self.navigationController setDelegate:self]; 

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

我不确定这是我解决的同样的问题。
在某些情况下,方法不会以正常的方式执行,如“[self methodOne]”。

尝试

 - (void)viewWillAppear:(BOOL)animated { [self performSelector:@selector(methodOne) withObject:nil afterDelay:0]; } 

您应该只有1个UIViewController在任何时候活动。 你想要操纵的任何子视图都应该是 – subVIEWS – 即UIView。

我使用一种简单的技术来pipe理我的视图层次结构,并且在我开始这样做的时候还没有遇到问题。 有两个关键点:

  • 应该使用一个UIViewController来pipe理你的应用程序的“屏幕值”
  • 使用UINavigationController来改变视图

“屏幕的价值”是什么意思? 目的有点模糊,但通常是应用程序的function或部分。 如果你有几个屏幕具有相同的背景图像,但不同的叠加/popup等,应该是1视图控制器和几个子视图。 你永远不应该发现自己使用2个视图控制器。 注意你仍然可以在一个视图控制器中实例化一个UIView,并将其作为另一个视图控制器的子视图添加,如果你想要在多个视图控制器中显示屏幕的某些区域。

至于UINavigationController – 这是你最好的朋友! closures导航栏并将animation指定为NO,并且您可以根据需要切换屏幕。 如果视图控制器处于层次结构中,则可以推送和popup视图控制器,也可以准备视图控制器数组(包括包含单个VC的数组),并使用setViewControllers将其设置为视图堆栈。 这让你可以完全自由地改变风险投资,同时获得苹果公司预期模式的所有优势,让所有事件得到正确的解决。

以下是我每次启动应用时所做的工作:

  • 从基于窗口的应用程序开始
  • 添加一个UINavigationController作为窗口的rootViewController
  • 添加任何我想我的第一个UIViewController作为导航控制器的rootViewController

(注意从基于窗口的开始只是个人偏好 – 我喜欢自己构build东西,所以我知道它们是如何构build的,它应该可以在基于视图的模板中正常工作)

所有的事件都是正确的,基本上生活是好的。 然后,您可以将所有时间花在编写应用程序的重要部分,而不是尝试手动将视图层次结构化为形状。