present和push的比较
1.present和push都用于iOS的视图切换,并且控制器切换都是可逆的,原始视图不会被销毁。还有一种切换视图的方式切换window的rootViewController是不可逆的,且原始视图会被销毁。
2.present一般用于不同业务界面的切换,push一般用于同一业务不同界面的切换。
3.present和dismiss对应,push和pop对应
4.present只能逐级返回,push虽有视图由栈控制,可以返回任意级
push方法
//创建新的视图控制器
VCSecond* vcSecond = [[VCSecond alloc] init];
//使用当前视图控制器的导航控制器对象
[self.navigationController pushViewController:vcSecond animated:YES];
pop方法
//将当前视图控制器弹出,返回上一级界面
[self.navigationController popViewControllerAnimated:YES];
//返回到根视图
[self.navigationController popToRootViewControllerAnimated:YES];
//返回到任意视图
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
popToViewController-xxx就是跳转到指定的视图控制器xxx,这个xxx一定要在这个栈里面,即一定是在我们当前这个视图控制器的下面的,所以跳转也就是把自己和在xxx上面的所有视图控制器都pop出去,然后相当于直接跳转到xxx。如何获取你要跳转到的视图控制器呢?self.navigationController.viewControllers出场,viewControllers是个数组,储存的时导航控制器栈中所有的视图控制器,最先push进去的时0,以此类推,最上面的肯定是数组的最后一个。所以,那个xxx之前初始化的对象,可以用[self.navigationController.viewControllers objectAtIndex:0]表示,此处0就是根视图控制器。
present方法
VCSecond* vcSecond = [[VCSecond alloc] init];
[self presentViewController:vcSecend animated:YES completion:nil]; //跳转到vcSencend所在视图
dismiss方法
[self dismissModalViewControllerAnimated:YES]; //退出当前视图
下面是dismiss多级视图的方法
dismiss到最初的视图
-(void)dismissToRootViewController {
UIViewController *vc = self;
while (vc.presentingViewController) {
vc = vc.presentingViewController;
}
[vc dismissViewControllerAnimated:YES completion:nil];
}
dismiss两级视图
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
dismiss到任意目标视图
UIViewController *rootVC = self;
while (![rootVC isKindOfClass:[ViewController class]]) {
rootVC = rootVC.presentingViewController;
}
[rootVC dismissViewControllerAnimated:YES completion:nil];
先了解下presentedViewController和presentingViewController
presentedViewController和presentingViewController是UIViewController里面的两个属性
PresentedViewController 与 PresentingViewController区别
presentedViewController:The view controller that was presented by this
view controller or its nearest ancestor. 由这个视图控制器或它最近的祖先呈现的视图控制器
presentingViewController:The view controller that presented this view
controller (or its farthest ancestor.) 呈现此视图控制器(或其最远祖先)的视图控制器。
A控制器present B控制器,则
A.presentedViewController = B;
B.presentingViewController = A;
注意上面的方法都是先找到你要返回到的视图控制器再用这个视图控制器调用dismiss方法。和当前视图控制器直接调用dismiss方法,回到上一视图不同。
//在B中
//返回上一级 两种写法效果一样
[self dismissViewControllerAnimated:NO completion:nil];
[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
即在B中调用dismiss方法,dismiss方法会自动交给B的presentingViewController即A视图中执行。
对于A->B->C->D,由D dismiss到A;那么对于A中执行dismiss而实现多级跳转到A的解释
即present多个视图控制器的时候,系统维护了一个栈,栈底到栈顶A->B->C->D,当在A执行dismiss,栈中在A之上的视图都会被dismiss。不同的是栈顶的视图控制器将会以动画的方式被dismiss掉,而中间的视图控制器只是简单的remove掉。