iOS开发——Xcode11新工程页面跳转向低版本兼容问题

文章目录

  • 1.写在前面
  • 2.Xcode11的mainStoryboard实现页面跳转
    • 2.1添加一个要跳转到的ViewController
    • 2.2非代码实现一个页面的跳转
    • 2.3代码实现一个页面跳转
      • 2.3.1 Storyboard中设置ViewController的身份
      • 2.3.2 实现button点击功能
      • 2.3.3 实现页面跳转的功能
        • 方法一的实现:
        • 方法二的实现:
      • 2.3.4 实现页面回退的功能
  • 接下来,将是这篇文章的重点,正如题目所说,兼容问题与适配解决方案
  • 3. iOS13与低于iOS13系统差异
    • 3.1 Modal Presentation Styles(弹出风格)的改变
    • 3.2 遇到的问题及解决的方法

1.写在前面

 
  我是从今年的10月份,也就是Xcode11版本开始接触iOS开发的,因此对于各个版本之间的差异了解的不多,开始接触iOS开发也是从iOS13版本开始的,在自测过程中,发现了工程版本不能向下兼容的问题,相应的原因与解决办法,已经在我的其他文章中有所提及,而且正在慢慢补充的过程中,如果有大佬看到文章中的错误,请及时与我联系,谢谢!

2.Xcode11的mainStoryboard实现页面跳转

 
  之前做过C#的客户端和asp.net的项目,感觉iOS应该也有类似于控件的拖拽功能,要不然时刻计算坐标位置岂不是太麻烦。终于功夫不负有心人,最终找到了控件的位置。如图

 
  既然说到这里了,这里就介绍一下利用mainStoryboard的button实现页面跳转的功能,通过这种方式形成的新页面,无需写一些关于回退的功能,这是它的优点
  有优点,必定对应有缺点,毕竟偷懒的方式实现的功能,多多少少都会存在一些解决不了的问题,缺点我们后面介绍,先说说如何去实现这个页面跳转的(其实我记得这块我都写过了。。。可是怎么样也找不到在哪里写的了。。。那就再写一次),好了废话不多说。

2.1添加一个要跳转到的ViewController

 

  双击后,在Storyboard中会生成一个新的ViewController,然后在主ViewController中添加一个button。
iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第1张图片

2.2非代码实现一个页面的跳转

 
  选中button,按住control键,拖拽到如图所示位置,然后选择相应的显示方式即可。
 如图所示
iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第2张图片
iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第3张图片
 
  这里我选择的是show的方式,其他方式也可以选择,只不过show在iOS13里面用的普遍,后面会介绍一下页面跳转的不同与改变。这样,一个简单的页面跳转和跳回功能就实现了,就不在这里演示了,因为这个太简单了。自己操作一次就可以了。

2.3代码实现一个页面跳转

2.3.1 Storyboard中设置ViewController的身份

 
  一个ViewController对应着一对相应的.m/.h文件,设置方式如下,首先新建一个类,继承自UIVIewController,然后在Storyboard中设置。

这样就可以在secondViewController.m文件中控制对应的页面中控件。

2.3.2 实现button点击功能

iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第4张图片
iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第5张图片
  创建点击后的action动作,然后在里面写相应的功能就可以了。
iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第6张图片

2.3.3 实现页面跳转的功能

 
  由于Xcode的不断进化,曾经的方法presentModalViewController已经弃用。

[self presentModalViewController:<#(nonnull UIViewController *)#> animated:<#(BOOL)#>];

 
  当前采用的页面跳转方法是下边两种

//方法一
[self.navigationController pushViewController:vc animated:YES];
//方法二
[self presentViewController:vc animated:YES completion:nil];

接下来将分别介绍一下两种跳转方法的不同,以及在不同情况下的ViewController的初始化。

方法一的实现:

 
  分为三种情况:

  1. 不带任何布局文件的viewController之间的跳转
secondViewController *vc = [[secondViewController alloc]init];
[self.navigationController pushViewController:vc animated:YES];
  1. 带.xib布局文件的viewController之间的跳转
secondViewController *vc = [[secondViewController alloc]initWithNibName:@"secondViewController" bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
  1. 带.storyboard布局文件的viewController之间的跳转
secondViewController *vc = [[UIStoryboard storyboardWithName:@"secondViewController" 
bundle:nil] instantiateInitialViewController];
[self.navigationController pushViewController:vc animated:NO];

方法二的实现:

 
  同样分为三种情况:

  1. 不带任何布局文件的viewController之间的跳转
secondViewController *vc = [[secondViewController alloc]init];
[self presentViewController:control animated:YES completion:nil];
  1. 带.xib布局文件的viewController之间的跳转
secondViewController *vc = [[secondViewController alloc]initWithNibName:@"secondViewController" bundle:nil];
[self presentViewController:control animated:YES completion:nil];
  1. 带.storyboard布局文件的viewController之间的跳转
secondViewController *control = [self.storyboard instantiateViewControllerWithIdentifier:@"secondViewController"];
[self presentViewController:control animated:YES completion:nil];

2.3.4 实现页面回退的功能

方法一的回退方式,可以自行百度一下,因为push进来的,采用pop就可以返回去,毕竟是个压栈的操作方式。
  这里着重分享一下方法二的回退,假如说从页面A preset 到页面B 再 preset 到页面C ,如果想回到页面A ,只需要执行下面这条语句就可以了。

[self.presentingViewController.presentingViewController  dismissViewControllerAnimated:YES completion:nil];

这个可以说是最简单的回退了,present了几个就presenting几个就可以了。有关present于dismiss的详细介绍可以参考这篇文章:你真的了解iOS中控制器的present和dismiss吗?

接下来,将是这篇文章的重点,正如题目所说,兼容问题与适配解决方案

3. iOS13与低于iOS13系统差异

3.1 Modal Presentation Styles(弹出风格)的改变

 
  在iOS 13之前,我们模态展示的视图默认是全屏的,而在iOS13中,默认的样式变成了类iPhone上safari的分页样式:
 iOS开发——Xcode11新工程页面跳转向低版本兼容问题_第7张图片
 
  而在低于iOS13版本的系统中,并不支持这种展示效果。这就是前面提及到的show的展示方式,在低于iOS13(后面统称低版本)的手机中,还是以全屏的效果显示。
  在使用 presentViewController 来跳转视图时系统提供了两个参数来简化跳转的设置,modalTransitionStylemodalPresentationStyle。前者为转场过渡的类型,后者为展示的样式,系统为两者都提供了多种可选样式。
  modalPresentationStyle(该属性是控制器在模态视图时将要使用的样式)没有设置需要的类型。在iOS13中modalPresentationStyle的默认改为UIModalPresentationAutomatic,而在低版本中默认是UIModalPresentationFullScreen
  
  另外补充一下其他的几种状态
  UIModalPresentationFullScreen:代表弹出VC时,presented VC充满全屏,如果弹出VC的wantsFullScreenLayout设置为YES的,则会填充到状态栏下边,否则不会填充到状态栏之下。
  UIModalPresentationPageSheet:代表弹出是弹出VC时,presented VC的高度和当前屏幕高度相同,宽度和竖屏模式下屏幕宽度相同,剩余未覆盖区域将会变暗并阻止用户点击,这种弹出模式下,竖屏时跟UIModalPresentationFullScreen的效果一样,横屏时候两边则会留下变暗的区域。
  UIModalPresentationFormSheet:这种模式下,presented VC的高度和宽度均会小于屏幕尺寸,presented VC居中显示,四周留下变暗区域。
  UIModalPresentationCurrentContext:这种模式下,presented VC的弹出方式和presenting VC的父VC的方式相同。
  这四种方式在iPad上面统统有效,但在iPhone和iPod touch上面系统始终已UIModalPresentationFullScreen模式显示presented VC。

3.2 遇到的问题及解决的方法

 
  在工程中,由于模型的加载与卸载分别放置在了viewWillAppearviewWillDisappear中,在页面即将加载或即将消失的时候,这两个方法里面的内容会自动调用,因此,这个模型的加载与卸载跟页面的生命周期紧密的联系起来。
  在iOS13及以上系统中,采用刚刚默认的方式,即UIModalPresentationAutomatic方式加载的页面,A 进入 B后,A页面会挂起,不会执行viewWillDisapper,但是在低版本中,默认的是UIModalPresentationFullScreen,出现了模型的卸载,这个问题没有查找到什么原因,初步认为,在低版本中,当前的A页面被B页面覆盖掉,系统认为当前页面已经Disappear了。
  这个问题相当的棘手,因为设置UIModalPresentationAutomatic的话,低版本的系统会报错,没有这个枚举类型。因此采用根据手机系统是否为iOS13版本为界限,调用不同的方法。
  解决方法:
  iOS13及以上的版本仍采用present方法,低版本系统,采用加载子视图的方式来实现页面生命周期的维持,同时加载下一个页面的功能,但是这个方法的使用中,一定要切记,父级视图一定不要有任何UI刷新的操作,放置内存占用率过高。

secondImageViewController *control = [self.storyboard instantiateViewControllerWithIdentifier:@"secondImageViewController"];
 if (@available(iOS 13.0, *)){
        [self presentViewController:control animated:YES completion:nil];
    } else {
        control.view.frame = self.view.bounds;
        [self.view addSubview:control.view];
        [self addChildViewController:control];
    }
//页面回退,删除子视图就可以了。
[self.view removeFromSuperview];

至此,这个问题可以说是规避掉了。

你可能感兴趣的:(iOS开发)