美文网首页iOS程序猿iOS DeveloperiOS学习笔记
完美解决LaunchScreen.storyboard启动图更新

完美解决LaunchScreen.storyboard启动图更新

作者: Jonrencxr | 来源:发表于2022-01-25 17:33 被阅读0次

    背景

    在不久前接到了换壳工程的项目后,为了能够快速部署新的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%成功且稳定的方案:

    1. 新建不同名称的启动页.storyboard,作为启动页,并删除旧的。
    2. 新的启动图片需要重新命名,并且需要放在工程文件夹下(无需根目录),不能放在Assets里面。
    这二者缺一不可 !!!

    简单步骤

    防止部分小伙伴理解偏差,我贴下步骤图:

    1. 假如原来的启动图为:Launch Screen.storyboard


      image.png
    2. 可以新建个故事版叫:NBLaunchScreen.storyboard,然后重新添加ImageView设置约束,添加启动图片,重新设置为启动图。


      image.png
    3. 假设原来的图片名称为launch.png,新的启动图命名为start0.png,并设置为启动图


      image.png

    完美,收工,适用于任何场景,启动图立即更新,不掺杂任何杂质。

    重要补充

    在执行前面的步骤后,若再有新的启动图更换需求,使用上次的启动页.storyboard即可,比如上次已经改为:NBLaunchScreen.storyboard,本次就无须改名了,只需更改图片名称并重新添加到NBLaunchScreen.storyboard就行,同时支持不同旧版本升级替换,也就是说,苹果只会对默认的Launch Screen.storyboard进行故事版的缓存。

    知识点+小妙招

    1. 苹果对启动图的缓存应该同时使用了storyboard+图片作为索引。
    2. storyboard比LaunchImage(Assets)优先级高,前者方案可以更改为后者,但是后者不可更改为前者。
    3. storyboard上的图片建议设置Aspect Fit自适应,图片建议用一张1242 × 2688尺寸的(高度最高的),设计图案尽量靠中间并且整个图片透明,storyboard的view层设置背景颜色,这样不同机型包括iPad都能适配。
    4. 预祝正在阅读的你春节快乐。

    相关文章

      网友评论

        本文标题:完美解决LaunchScreen.storyboard启动图更新

        本文链接:https://www.haomeiwen.com/subject/xliwhrtx.html