使用addSubView时,viewWillAppear不会运行!
使用addSubView时,viewWillAppear不会运行!
我卡住了!我不明白为什么viewWillAppear在我的代码中没有运行,但viewDidLoad是运行的。如果我理解正确,viewDidLoad在第一次实例化时运行一次,而viewWillAppear在每次将视图添加到要显示的视图堆栈时运行。
我看到其他人也遇到了这个问题,但是他们直接调用viewWillAppear的解决方案却导致我的应用程序崩溃。其他解决方案与导航控制器和推送视图有关,但我也没有使用它们!我错过了什么?
非常感谢您的帮助! 🙂
请参见以下代码:
视图控制器#1 - 当前显示在屏幕上
- (IBAction)someButtonPressed:(id)sender { NSLog(@“FirstViewController - someButtonPressed”); SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@“SecondViewController” bundle:nil]; secondViewController.myLocation = self.myLocation; secondViewController.myDatabase = self.myDatabase; [self.view addSubview:secondViewController.view]; //[secondViewController viewWillAppear:YES]; }
SecondViewController:
- (void)viewWillAppear:(BOOL)animated { NSLog(@“SecondViewController - viewWillAppear”); [super viewWillAppear:animated]; // 更新数据的实例变量 } //实现viewDidLoad以在加载视图后进行其他设置,通常是从nib加载 - (void)viewDidLoad { NSLog(@“SecondViewController - viewDidLoad”); [super viewDidLoad]; }
问题的出现原因是:使用addSubView方法添加视图时,viewWillAppear方法不会被调用。原因是UIKit假设UIViewController的视图将填充整个窗口,因此嵌套UIViewControllers的视图会导致意外行为。
解决方法是:不要在UIViewController的视图中嵌套其他UIViewController的视图。可以使用导航控制器(NavControllers)、标签控制器(TabControllers)或自定义控制器(MyCustomControllers)来实现在当前视图控制器上叠加其他视图控制器的完整视图。
这样做的原因是,addSubView方法更适用于向视图控制器添加较小的视图,例如UILabel、UIImage、自定义UIView等,这些都将组成当前视图控制器的视图。而不是将完整的视图控制器堆叠在当前视图控制器上。
每个子视图仍然可以有负责管理它们的控制器对象,但它们的控制器不应该是UIViewController。例如,可以将UITableView作为子视图,并使用一个控制器作为其委托和数据源。这样可以避免使用单个庞大的控制器类。
需要注意的是,以上解决方法是针对iOS 5版本之前的情况。在iOS 5及更高版本中,可以创建容器视图控制器,其子视图控制器可以管理父视图的一小部分。但仍然需要使用框架中适当的添加/移除子视图控制器方法,以确保UIViewController的方法(如-viewWillAppear:)在预期时被调用。
问题的原因是,当使用addSubview:
方法将一个视图添加到父视图上时,并不会触发viewWillAppear:
方法。而viewWillAppear:
方法只会在视图控制器以正常方式显示时被调用,例如通过选择UITabBarController
中的一个标签、通过推入UINavigationController
中,通过从UINavigationController
中弹出,通过使用presentModalViewController:animated:
显示,通过使用dismissModalViewControllerAnimated:
隐藏后再次显示等等。
解决方法是,可以手动正确调用viewWillAppear:
方法,但一般来说最好使用上述提到的正常方式之一来触发该方法。