一、基本区别
pushViewController 导航控制器入栈的方式切换页面
presentViewController 模态切换的方式切换页面
二、对生命周期的影响
[self presentModalViewController:controller animated:YES];
self 不会调用dealloc自我销毁。
self.set 只会再第一次出现时调用ViewDidLoad加载,之后再执行该函数时只会调用:(void)viewWillAppear:(BOOL)animated;
[self dismissModalViewControllerAnimated:YES];
self 会调用dealloc
self之下的一个Controller会调用(void)viewWillAppear:(BOOL)animated;
[self.navigationController pushViewController:controller animated:YES];
上层的ViewController会调用viewdidload.
[self.navigationController popViewControllerAnimated:YES];
上层的ViewController会调用dealloc
三、 A -> B -> C,在 C 中直接返回 A
3.1 用present实现的方法
C中返回事件 :
- (void)back
{
[self dismissModalViewControllerAnimated:NO]; // 注意一定是NO
[[NSNotificationCenter defaultCenter]postNotificationName:@"backback" object:nil];
}
然后在B中 :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(back) name:@"backback" object:nil];
-(void)back
{
[self dismissModalViewControllerAnimated:YES];
}
3.2 pop的实现方法
返回到指定的控制器,要保证前面有入栈。
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:2] animated:YES];
也可以指定一个特定的控制器:
for (UIViewController *controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[NeedBackViewController class]]) {
NeedBackViewController *vc = (NeedBackViewController *)controller;
[self.navigationController popToViewController:vc animated:YES];
}
}
四、判断当前是pop还是dismiss
4.1 通过判断self有没有present方式显示的父视图presentingViewController
- (IBAction)dismiss:(id)sender {
if (self.presentingViewController) {
[self dismissViewControllerAnimated:YES completion:nil];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
4.2 通过判断self.navigationController.viewControllers的最后一个是否是当前控制器,或者self.navigationController.topViewController == self
- (IBAction)dismiss:(id)sender {
if (self.navigationController.topViewController == self) {
[self.navigationController popViewControllerAnimated:YES];
} else {
[self dismissViewControllerAnimated:YES completion:nil];
}
}