背景
在不久前接到了換殼工程的項目后,為了能夠快速部署新的APP,啟動圖由原來的LaunchImage(Assets)改為LaunchScreen.storyboard故事版方案,只需提供一張圖即可快速更新啟動圖,后者也是蘋果官方最為推薦的方式。然而,剛剛接收到新的需求是更新啟動圖,換圖之后不生效,最后重啟手機重裝APP才生效,但是這種極差的用戶體驗就別拿出來說事了。
原因
通過谷歌得知,蘋果系統(tǒng)對LaunchScreen.storyboard設置的啟動圖有緩存,因此不能及時更新,至于多久能更新,不知道,也等不起。
谷歌方案
通過谷歌,各路大神各顯神通,有說重啟Xcode的、清理Xcode緩存的、卸載APP的、重啟手機的、有說圖片改名字的、有說改為LaunchImage模式的、也有說刪除系統(tǒng)緩存的啟動圖的,甚至貼出了代碼:
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];
}
我想說的是,各位大神,您試了,各種場景下,真的都沒問題嗎?
建議,自測真正有效并且穩(wěn)定的方案再貼出來,防止更多人迷路。但是,還是要感謝這么多的技術大神,勇于分享自己的實踐和理解,值得我們大家學習。
完美方案
廢話話不多說,100%成功且穩(wěn)定的方案:
- 新建不同名稱的啟動頁.storyboard,作為啟動頁,并刪除舊的。
- 新的啟動圖片需要重新命名,并且需要放在工程文件夾下(無需根目錄),不能放在Assets里面。
這二者缺一不可 ?。。?/h6>
簡單步驟
防止部分小伙伴理解偏差,我貼下步驟圖:
-
假如原來的啟動圖為:Launch Screen.storyboard
image.png -
可以新建個故事版叫:NBLaunchScreen.storyboard,然后重新添加ImageView設置約束,添加啟動圖片,重新設置為啟動圖。
image.png -
假設原來的圖片名稱為launch.png,新的啟動圖命名為start0.png,并設置為啟動圖
image.png
完美,收工,適用于任何場景,啟動圖立即更新,不摻雜任何雜質(zhì)。
重要補充
在執(zhí)行前面的步驟后,若再有新的啟動圖更換需求,使用上次的啟動頁.storyboard即可,比如上次已經(jīng)改為:NBLaunchScreen.storyboard,本次就無須改名了,只需更改圖片名稱并重新添加到NBLaunchScreen.storyboard就行,同時支持不同舊版本升級替換,也就是說,蘋果只會對默認的Launch Screen.storyboard進行故事版的緩存。
知識點+小妙招
- 蘋果對啟動圖的緩存應該同時使用了storyboard+圖片作為索引。
- storyboard比LaunchImage(Assets)優(yōu)先級高,前者方案可以更改為后者,但是后者不可更改為前者。
- storyboard上的圖片建議設置
Aspect Fit自適應,圖片建議用一張1242?×?2688尺寸的(高度最高的),設計圖案盡量靠中間并且整個圖片透明,storyboard的view層設置背景顏色,這樣不同機型包括iPad都能適配。 - 預祝正在閱讀的你春節(jié)快樂。


