【iOS】push&pop和present&dismiss的区别及混用

在开发过程中,我们有时会遇到界面切换问题,有两种基本的方式可以实现界面切换:

  • push方法,将界面从右侧推进来,借助的是导航控制器,在新界面会有导航控制器,并且左上角会自动生成一个导航栏按钮可以返回上一层级,当然要想自定义返回按钮就得在按钮的点击事件中借助pop方法
  • present方法,将页面从下侧切进来,返回上一层级则需要dismiss方法

push和present相同点

push和present都可以推出新的界面

  • push与pop对应

先在window上加一个navigation,然后以VCRoot作为navigation的根视图进行导航

    UIWindowScene* windowScene = (UIWindowScene *)scene;
    self.window = [[UIWindow alloc] initWithWindowScene: windowScene];
    self.window.frame = windowScene.coordinateSpace.bounds;
    
    //将window根视图设置成navigation
    UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController: [[VCRoot alloc] init] ];
    self.window.rootViewController = navigation;
    
    [self.window makeKeyAndVisible];

接下来在VCRoot界面使用push和pop切换其他界面

    //创建新的视图控制器
    NewViewController* newViewController = [[newViewController alloc] init];
    //推出新的视图
    [self.navigationController pushViewController: newViewController animated: YES];
    
    //返回上一层级
    [self.navigationController popViewControllerAnimated: YES];
    //返回根视图
    [self.navigationController popToRootViewControllerAnimated: YES];
    //返回指定视图
    [self.navigationController popToViewController: newViewController animated: YES];
    //返回指定级数,此处为第一层级
    [self.navigationController popToViewController: [self.navigationController.viewControllers objectAtIndex: 0 ] animated: YES];
  • present与dismiss对应
    //创建新的视图
    NewViewController* newViewController = [[newViewController alloc] init];
    
    //推出新的视图
    [self presentViewController: newViewOCntroller animated: YES completion: nil];
    //返回上一层级
    [self dismissViewControllerAnimated: YES completion: nil];

现在新版本的present并没有将新视图显示完全,因此可以拖拽新视图返回上一层级
要想将present来的视图显示完全,占满整个屏幕,可以使用以下代码:

newViewController.modalPresentationStyle = UIModalPresentationFullScreen;

present和pop不同点

从上面的代码我们可以看出,push可以返回指定层级的视图,而present不可以,只能逐级返回,这是因为push的所有视图由视图控制

我们可以回想一下平时用的App,是不是不同业务界面的切换用的都是present,同一业务不同界面之间的切换用的都是push


以下是几个在写项目过程中遇到的问题

导航控制器消失🫠

如果在导航之间有了一个present之后,你会发现当前页面的navigationController是空的,也就是说导航控制器不管用了

解决办法是获取当前的window实例,在得到window的根视图,即为导航器,然后根据导航器的索引就可以找到当前的视图

// 先取消原来的控制器
  [self dismissViewControllerAnimated:NO completion:nil];
  ViewController *VC=[[ViewController alloc]init];  
  UIWindow *window=[[UIApplication sharedApplication]keyWindow];  
  UINavigationController *nav0=(UINavigationController *)window.rootViewController;  
  UIViewController *viewController=[nav0.viewControllers objectAtIndex:1];  
  [viewController.navigationController pushViewController:VC animated:YES];  

判断当前viewcontroller是push还是present的方式显示的

NSArray *viewcontrollers=self.navigationController.viewControllers;
if (viewcontrollers.count>1) {
    if ([viewcontrollers objectAtIndex:viewcontrollers.count-1]==self) {
        //push方式
        [self.navigationController popViewControllerAnimated:YES];
    }
}
else{
    //present方式
    [self.navigationController dismissViewControllerAnimated:YES completion:nil];
}

通过present的方式显示的viewController不会存入self.navigationController.viewControllers数组中

而通过push方式显示的viewcController会存在该数组的最后

隐藏push界面的返回键

要隐藏push来的界面自动生成的返回键,只需以下一句代码:

self.navigationItem.hidesBackButton=YES;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值