背景
在不久前接到了换壳工程的项目后,为了能够快速部署新的APP,启动图由原来的LaunchImage(Assets)改为LaunchScreen.storyboard故事版方案,只需提供一张图即可快速更新启动图,后者也是苹果官方最为推荐的方式。然而,刚刚接收到新的需求是更新启动图,换图之后不生效,最后重启手机重装APP才生效,但是这种极差的用户体验就别拿出来说事了。
原因
通过谷歌得知,苹果系统对LaunchScreen.storyboard设置的启动图有缓存,因此不能及时更新,至于多久能更新,不知道,也等不起。
谷歌方案
通过谷歌,各路大神各显神通,有说重启Xcode的、清理Xcode缓存的、卸载APP的、重启手机的、有说图片改名字的、有说改为LaunchImage模式的、也有说删除系统缓存的启动图的,甚至贴出了代码:
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/SplashBoard/Snapshots"];
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
甚至更加复杂的代码:
float systemVersion = [[UIDevice currentDevice].systemVersion floatValue];
if (systemVersion >= 13.0 && systemVersion < 14.0) {
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *folderPath = [documentsPath stringByAppendingPathComponent:@"Data"];
NSString *imageCachePath = [folderPath stringByAppendingPathComponent:@"SplashBoard"]; // ~/Documents/Data/SplashBoard
// 准备
BOOL isDirectory = YES;
if (![[NSFileManager defaultManager] fileExistsAtPath:folderPath isDirectory:&isDirectory]) {
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSError *error = nil;
// 1.获取Images.xcassets中启动图
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil];
NSAssert(sb != nil, @"未找到 LaunchScreen.storyboard 文件");
UIViewController *vc = [sb instantiateInitialViewController];
UIImage *currentImage = nil;
for (UIView *subview in vc.view.subviews) {
if ([subview isKindOfClass:[UIImageView class]]) {
currentImage = ((UIImageView *)subview).image;
break;
}
}
if (currentImage == nil) {
NSAssert(currentImage != nil, @"LaunchScreen.storyboard 中缺少 ImageView");
return;
}
NSData *currentData = UIImagePNGRepresentation(currentImage);
// 2.获取缓存的启动图
NSData *cachedData = [[NSData alloc] initWithContentsOfFile:imageCachePath];
if (cachedData && [cachedData isEqualToData:currentData]) {
return;
}
[[NSFileManager defaultManager] removeItemAtPath:[NSHomeDirectory() stringByAppendingString:@"/Library/SplashBoard"] error:nil];
[currentData writeToFile:imageCachePath atomically:YES];
}
我想说的是,各位大神,您试了,各种场景下,真的都没问题吗?
建议,自测真正有效并且稳定的方案再贴出来,防止更多人迷路。但是,还是要感谢这么多的技术大神,勇于分享自己的实践和理解,值得我们大家学习。
完美方案
废话话不多说,100%成功且稳定的方案:
- 新建不同名称的启动页.storyboard,作为启动页,并删除旧的。
- 新的启动图片需要重新命名,并且需要放在工程文件夹下(无需根目录),不能放在Assets里面。
这二者缺一不可 !!!
简单步骤
防止部分小伙伴理解偏差,我贴下步骤图:
-
假如原来的启动图为:Launch Screen.storyboard
image.png -
可以新建个故事版叫:NBLaunchScreen.storyboard,然后重新添加ImageView设置约束,添加启动图片,重新设置为启动图。
image.png -
假设原来的图片名称为launch.png,新的启动图命名为start0.png,并设置为启动图
image.png
完美,收工,适用于任何场景,启动图立即更新,不掺杂任何杂质。
重要补充
在执行前面的步骤后,若再有新的启动图更换需求,使用上次的启动页.storyboard即可,比如上次已经改为:NBLaunchScreen.storyboard,本次就无须改名了,只需更改图片名称并重新添加到NBLaunchScreen.storyboard就行,同时支持不同旧版本升级替换,也就是说,苹果只会对默认的Launch Screen.storyboard进行故事版的缓存。
知识点+小妙招
- 苹果对启动图的缓存应该同时使用了storyboard+图片作为索引。
- storyboard比LaunchImage(Assets)优先级高,前者方案可以更改为后者,但是后者不可更改为前者。
- storyboard上的图片建议设置
Aspect Fit
自适应,图片建议用一张1242 × 2688尺寸的(高度最高的),设计图案尽量靠中间并且整个图片透明,storyboard的view层设置背景颜色,这样不同机型包括iPad都能适配。 - 预祝正在阅读的你春节快乐。
网友评论