苹果强制要求更换启动方式的解决方案
苹果要求:2020年June 30之前必须将启动方式通过
storyboard
进行加载。具体参考官方文档(https://developer.apple.com/news/?id=03262020b)。或者可以直接看下面的截图。
注意:启动图如果设置的不正确,那么会影响自己App的主页内容。可能会产生拉伸等问题,这个会在后面详细说明。
准备工作
1. 关于LaunchImage和LaunchScreen.storyboard技术背景
LaunchImage
和LaunchScreen.storyboard
都是加载启动图的一种方式,但是二者有很大区别:
LaunchImage
出现的要比LaunchScreen.storyboard
早些, iOS8以后开始支持LaunchScreen.storyboard
LaunchScreen.storyboard
的默认优先级高于LaunchImage
LaunchScreen.storyboard
适配的更灵活些,类似于新做一个界面。LaunchImage
只是固定加载image set
中的几个图。二种方式尽量不要混用,会有很多不可预知的问题
2. 替换前的一些准备工作
在真正替换之前需要做些准备工作,这里不涉及设计那边的工作,只说一下我们技术相关的。
a) 删除settiing中旧的LaunchImage加载方式设置
b)删除Asset中旧的启动图
这些旧的启动图都要删掉,这样也可以减少包的体积,以后这些都用不上了,另外需要说一下这里的图片最大的也是375 * 812
的,这样的对于打手机例如414 * 896
的,其实主页会有一定的拉伸,最直观的感受就是UI不一样了,这个后面会详细叙述。
c)工程配置新的storyboard启动方式
下面就是在工程设置中设置新的启动方式。
d)代码层面
其实代码层面我们开发人员可以做的已经很少或者说没有了,因为在进入app程序willFinishLaunchingWithOptions
的时候,启动图已经出来了,应该就是iOS系统对App启动图的缓存。目的就是立即显示,增强用户的体验。
是否要新加代码清除缓存,这个就看自己了,有的兄弟公司就是没加任何清除缓存的代码,我这里就清除了下/Library/SplashBoard
和/Library/Caches/Snapshots
目录里的缓存。策略就是检测版本号不同的时候启动就清除下。
几种技术方案
这里首先是要新建一个storyboard
,直接新建就行,用苹果给提供的启动页面的storyboard
模板。
启动图的storyboard
可以当做普通页面去处理了,拖进去控件并设置约束。
下面就是处理新建的启动图的storyboard
,有几种处理方案。
1. 只放一张图
这个有人这么做,就是放一张图,按比例进行填充aspect fill
。好处就是资源文件只有一张图很省空间,缺点就是不同屏幕的尺寸由于比例扩张和收缩,那么会有部分信息显示不全。
2. 加图片集多张图
这个是新建一个图片集image set
里面放各种尺寸的iphone
和ipad
的图片。
这个方案可以很完美不会有任何拉伸问题,而且做起来开发者的工期也不需要,直接就是图片的替换。缺点就是以后机器尺寸多了就要多放图,图都是高清的,即使进行了压缩,那包的体积也会加大很多。
3. 将素材进行分割加载,当成普通的storyboard文件进行处理
这个想法就是将启动图中的元素,包括logo,还有文字等单独切出来,然后像普通页面那样加载控件(UILabel、UIImageView)
等。
这解决了不同尺寸屏幕的适配问题以及包资源体积增大的问题。好处就是包体积小了适配各种机型更灵活(但是背景图还是不可避免的要失去部分显示效果),不好的地方就是以后要是换开屏图,那么就要开发者有一定的工作量进行处理。
综述,看上面三个方案,对比研究觉得最后这种方案是最靠谱的并进行了实践,这个也是苹果公司推荐的方案。
几个问题
1. 部分机型适配问题
个别流海屏手机,比如xsmax 12
系统机型,使用launchScreen.storyboard
加载启动图,启动图都是正常的,但是到了主页,看见了主页被拉伸,底部的tabBar
延伸到了下面的底部,到了安全区。而且亲测在某些xsmax13
系统的机型就是正常的。
具体如下图所示:
想了很多,为什么启动图正常,但是主页为什么冲出去安全区了呢?而且xsmax 13
系统正常,但是只是个别的xsmax 12
系统就不正常。
查了很多资料也不知道为什么,一开始一直怀疑是启动图做的launchScreen.storyboard
哪里做的不符合苹果的需求。但是找了很久也没发现哪里不对,况且在别的机型也是正常的。
所以有一种猜想,可能是我们自己的代码出问题了。
然后我就找了我们自定义的UITabBarController
那里的代码。
发现了一处代码:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if (!Is375x812hScreen()) {
self.tabBar.frame = CGRectMake(0, KScreenHeight - kDSTabBarHeight, CGRectGetWidth(self.tabBar.frame), kDSTabBarHeight);
}
}
#define Is375x812hScreen() (ABS((double)[[UIScreen mainScreen] bounds].size.height - 812.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.width - 812.f) < DBL_EPSILON) //iphoneX
这里,Is375x812hScreen()
是17
年iphoneX
出来的时候加的宏,后来xsmax
等896
高的屏幕出来了,进行了更改,改宏就用来定义流海屏了,但是我用真机跑代码的时候,我发现xsmax 12
系统的手机进入了if判断语句里面,也就是说被认为了不是流海屏,而用同事的手机xsmax 13
系统手机就不会进入if语句,就可以正确被判定是流海屏。我猜想应该就是启动图加载方式变了,所以导致了流程哪里发生了改变,从而使用个别机型系统宏判断出现了错误。
于是,我就修改了下宏,如下所示:
#define Is375x812hScreen() (ABS((double)[[UIScreen mainScreen] bounds].size.height - 812.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.width - 812.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.height - 896.f) < DBL_EPSILON || ABS((double)[[UIScreen mainScreen] bounds].size.width - 896.f) < DBL_EPSILON)
宏修改成这样,xsmax 12
系统的手机就被正确认定为流海屏,主页就显示正常了,主页就不冲出安全区了。
具体如下所示:
可以看见下面的安全区留出来了。
同样检查可以看见直播间还有群组页面个别机型也是显示异常了,都需要进行特殊处理和适配,难度不大就是需要心细。
同时,替换后个人中心页面的显示正常没那么拉伸了。
2. 黑屏问题
其实关于黑屏可以分解成下面二个详细的小问题:
1) 第一个问题就是和QA模拟版本迭代升级换启动图,发现的问题,就是升级版本号换启动图都正常,但是如果降低版本号,换启动图就是黑屏了。 2) 给背景图 UIImageView
设置backgroundColor
保护色,图片加载不出来的时候保护色不出来的问题。
说实话这二个问题,我们开发者可以活动或者解决的余地不是很大了。
先说第一个小问题。
1) 也许有人会问,用户都是升级,哪里来的降级呢,确实一般都是升级,但是也存在内测,升级版本,然后从 store
下载版本这种降版本的情况。当然这个是极特殊情况。
这个黑屏问题我真的尝试了不知道多少方法了,但是都不管用:
资源从 asset
和根目录来回换用兄弟公司App的启动图尝试 图片命名尽量别用 launch
开头清除沙盒里面 splashBoard
还有cache/snapshot
等目录缓存图片都打开或者关闭 alpha
通道
等等试了很多方法还是黑屏。只要是升高版本再降低版本,更换的启动图就不会生效,屏幕变黑。
但是这个问题真的自己无解了,毕竟我们程序员可以做的很少了,都是工程配置和一个自建立的storyboard
。storyboard
里毕竟只是imageView
的autolayout
。
所以这个问题暂时就是搁置了,只能暂时保证升级没问题就行。
下面说下第二个问题
2) 想着降低版本的话,图片image找不到的话,那就给 imageView
添加个保护色吧,这样不至于黑屏看着难受,可是问题出来了,如果设置了图片,图片没加载出来,imageView
的backgroundColor
是不生效的,还是黑色的;但是如果不设置图片名字,run一下就可以看见imageView
的背景保护色了。
这个问题我们也是无解的,这个像是什么呢?有点像iOS找不到图片默认给了个黑色的image
,所以后面的imageView
的背景保护色也是出不来的。
关于这个启动图的更换,想着很简单,但是却碰到了苹果的坑,在stackOverflow
上搜索,很多老外以前也遇到了这个问题。也是无解。这里其实有个解决办法,就是卸载App然后重启手机,在下载就都正常了,但是这个操作对于用户操作和体验却是致命的,不过还好版本号升级是没有问题的。猜测是苹果的缓存机制影响到的,这个需要苹果来完善了。