美文网首页iOS工作系列我的iOS开发小屋iOS精华
如何做到像百度云或者网易公开课一样动态更换APP启动图

如何做到像百度云或者网易公开课一样动态更换APP启动图

作者: 以技术之名 | 来源:发表于2016-04-12 21:25 被阅读6857次

    demo:https://github.com/Flying-Einstein/LaunchScreenTest喜欢就给个star吧

    常见的几种启动图风格

    • 静态图类型 :微信

      微信.gif
    • 图片不变,有动画效果 :京东

    京东.gif
    • 随着节日或者时间动态更换的 :百度云、网易公开课
    网易公开课 | 百度云.gif
    注意:笔者说的启动图并不是广告页,启动图是不接受点击事件的,但是广告页是接受点击事件的,点击后一般会跳转到网页。如下:
    有道词典.gif

    这几种风格的启动图怎么实现的?

    • 静态图类型 :这种比较简单,开发者可以使用LaunchImageLaunchScreen.storyboard的任何一种方式添加所需的正确格式的图片,但是在使用的过程中需要注意的事项,读者可以看我的这篇文章LaunchImage和LaunchScreen.xib混用出现的坑

    • 图片不变,有动画效果 :这种方式,笔者认为在实现方式上和第三种是一样的,就不在赘述,感兴趣的读者在看完第三种实现方式后,可以尝试去做。

    • 随着节日或者时间动态更换的 :这种方式,也就是笔者今天着重要讲的,原理及实现方式。

    像百度云或者网易公开课一样动态更换APP启动图原理

    • 其实你看到的不是一张图片 :读者仔细观察就会发现,使用这种方式的的启动图,用的不是一张图片,而是两张。我们拿百度云来举例:
      1.pic.jpg
      2.pic.jpg
      可以看到,两张图片的区别就是,底部都是一样的,而第一张上半部分是空白。其实,网易公开课和支付宝德也是如此。第一张图片是内容兼容性很强的图片,就是一个版权说明加上一个类似于app logo的样式,上面空白部分可以根据节日的不同,调整展示的样式
    • 这两张图片还有其他的不同吗 :因为笔者经常使用这几款app,发现有的时候第二张图片是不显示的,显示完第一张图片直接跳到app主页了。笔者认为,第一张图片就是放在[LaunchImage或者LaunchScreen.xib中的图片,是不会改变的。第二张图片则是从网上获取的,而且可以根据是否获取到相应的图片网址决定第二张图片能否显示。
    • 为什么要这么做 :有的读者可能有疑问,为什么要这么做?难道不可以直接更换掉第一张启动图吗,或者不显示第一张只显示第二张?答案:NO!
    • 更换第一张图片?抱歉,更换不了,如果你使用的是LaunchScreen.xib或者LaunchScreen.Storyboard,只要你的app启动过,那张图片就永远的缓存在app里了,以后每次启动都会出现。我的这篇简书讲过这个问题LaunchImage和LaunchScreen.xib混用出现的坑
    • 网络请求有延时,如果不放第一张图片,只放第二张图片,会出现短暂的黑屏。
    • 从产品的角度来讲,也不合理。比如:植树节的时候我展示了和环保有关的内容,如果过了植树节,那么正常情况下我不展示该内容就可以了,后台不返回相应的图片网址,展示完第一张图片就ok了。如果没有第一张图片,那么过了植树节,我就需要把网址更换,需要一个下载图片的过程,从用户体验来讲也不好,时间延迟也会浪费流量。

    关于猜测的一点验证?

    屏幕快照 2016-04-12 下午6.25.55.png

    这是一个post的请求方式,可以看到在url路径中,有image/diff这段,笔者判断这段路径返回 的参数是用来决定是否更换第二张图片的

    • 我们再来看第二张截图


      屏幕快照 2016-04-12 下午6.26.19.png

      紧接着第一次网络请求,就进行了这次网络请求,我们在path路径下可以看到app.gif,笔者认为这个网址就是图片的地址,百度云的第二张图片有动画效果,笔者猜测可能是gif格式的图片


    代码怎么实现这种启动图方式?

    • 第一张图片使用LaunchScreen.Storyboard方式
    • 这一步相信读者都会,笔者就不再赘述
    • 第二张图片如何展示
    • 第一步就是进行一次网络请求,判断有没有相应的图片网址,没有的话就就不显示,有的话拿到图片的网址进行第二次网络请求
    • 请求下来图片后,笔者参考通过LaunchScreen自定义启动动画实现启动图更换图片,而且可以给启动图添加动画效果
      ** 这一步是获取LaunchScreen.storyboard里的UIViewController,UIViewController 的identifer是LaunchScreen**
    UIViewController *viewController = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"LaunchScreen"];
        UIView *launchView = viewController.view;
        UIImageView  * Imageview= [[UIImageView  alloc]initWithFrame:[UIScreen mainScreen].bounds];
        [launchView addSubview:Imageview];
        [self.view addSubview:launchView];
    

    ** 这一步是获取上次网络请求下来的图片,如果存在就展示该图片,如果不存在就展示本地保存的名为test的图片**

    NSMutableData * data = [[NSUserDefaults standardUserDefaults]objectForKey:@"imageu"];
        if (data.length>0) {
             Imageview.image = [UIImage imageWithData:data];
        }else{
        
         Imageview.image = [UIImage imageNamed:@"Test"];
        }
    

    ** 下面这段代码,是调用AFN下载文件的方法,异步方式下载,但是在这里异步方式下载有一个问题,就是这次下载完成的图片,下次启动时才会展示,读者可以换成同步的,但是同步下载会有时间延迟,用户体验不好,下载完图片后,将图片以二进制的形式存在本地,笔者用的是userdefault,这是不科学的,读者可以存在其他文件夹,**

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        NSURL *URL = [NSURL URLWithString:@"http://s16.sinaimg.cn/large/005vePOgzy70Rd3a9pJdf&690"];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    
            NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
            return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
            NSLog(@"File downloaded to: %@", filePath);
            
            NSData * image = [NSData dataWithContentsOfURL:filePath];
            [[NSUserDefaults standardUserDefaults]setObject:image forKey:@"imageu"];
     }];
        [downloadTask resume];
    
    • 笔者在展示完第二张图片后,又添加了展示广告位的代码,这样就是app启动时比较完整的过程了。

    ** 这段代码,可以实现第二张图片有3D的动画效果,动画结束后,进行同步的网络请求,请求的是广告页图片,之所以用同步的是因为,如果用同步的话主页面显示后,图片才会加载完成显示。**

     [UIView animateWithDuration:6.0f delay:0.0f options:UIViewAnimationOptionBeginFromCurrentState animations:^{
            
            //launchView.alpha = 0.0f;
            launchView.layer.transform = CATransform3DScale(CATransform3DIdentity, 1.5f, 1.5f, 1.0f);
        } completion:^(BOOL finished) {
         
         
                    NSString * ad_imgUrl  = @"http://www.uimaker.com/uploads/allimg/121217/1_121217093327_1.jpg";
                    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
                    [BBLaunchAdMonitor showAdAtPath:ad_imgUrl
                                             onView:appDelegate.window.rootViewController.view
                                       timeInterval:5
                                   detailParameters:@{@"carId":@(12345), @"name":@"奥迪-品质生活"}];
                       [launchView removeFromSuperview];
        }];
    

    demo效果

    demo.gif

    总结:

    这是笔者的实现过程,希望可以给读者一点思路,如果读者觉得有什么不明白的,或者有更好的方式,希望能联系笔者,或者在评论中给出建议。

    如有转载,请告知笔者

    相关文章

      网友评论

      • 2ff28e499e10:资源我都有喜马拉雅得到网易确实内容丰富有内涵。需要咨询。
      • dcef36186569:很好很好!看了你的解释,我终于确定动态换不了启动图片了,平时是被假象蒙蔽了眼睛
      • vanessa_imp:其实就是广告页,第一次进去下载,保存图片信息,包括时间什么的,第二次进来根据时间判断是否展示。
      • 忘山老人:你好,在做需求的时候正好看到这里,但是我们的需求是这样的要求启动图从网络获取,但是启动图都是静态的啊,看过这篇文章后感觉还是无法实现。因为这个大概都是第一次是有静态启动图的,而后才会从网络获取图片作为广告图什么的对吧?楼主有什么好的思路提供给我么?
      • 会跳舞的狮子:请教下gif动态的 启动页
      • 士多啤:想做个类似豆瓣的启动页,他的是定时更新图片上的文字。

        但也有不同,豆瓣是根据本地时间更新,更容易。
        想做的展示读取到的文字,但可惜没有看过哪个APP有,不知实现效果如何
      • 7a946bf5d2ca:我看你动图也是黑色一闪而过
        7a946bf5d2ca:这样还是有瑕疵,不完美,标准的启动页不是这样
      • 7a946bf5d2ca:你的demo在启动的时候有个绿色的页面一闪而过,我看是LaunchScreen自身的view设置的背景颜色,请问,如何去掉这个颜色,即便设置clearcolor,是黑色一闪而过,让在一启动的一瞬间就是LaunchScreen上imageView的图片?
      • ForestSen:顶了!
      • sunhq:讲的很清楚,受教了
      • sensencoder:您好,有没有不要启动图直接广告,或者是启动图是直接从网络获取的呢??(第一次除外)谢谢。。
      • Swift_Aramis:雷哥,我打算这45天作战计划拼完了之后,自己着手做那个安卓的应用,刚好,你这个效果有用到
      • RadishHuang:如果用 launchImage 做启动页,那怎么去换图?拿不到launchImage吧?
      • Purlible:收藏之!
      • 空恋的爱:厉害!加油!
      • _YZG_:你好, 可以讲一下 BBLaunchAdMonitor类的实现吗
        以技术之名:@_YZG_ 布局有什么不懂得地方吗?是不是通知那里?通知那块没有用上,那是点击详情的时候用到的
        _YZG_:@Flying_Einstein 里面还有一些布局
        以技术之名:@_YZG_ 用的就是苹果本身的网络请求方式, 请求完成后才能进行动画操作
      • 华之曦:谢谢分享。
        以技术之名:@Huazhixi :smile:
      • 单身狗的清香:涨姿势了
      • 5e0d41867b23:很常见的广告页。现在所接触要做的App都会有。
        以技术之名:@雯籽雪 对的
        5e0d41867b23:@Flying_Einstein 现在接触的做法是启动页过后,展示和启动页相同的图片,同时请求数据,返回有广告就显示并多停几秒,返回无广告,就直接跳过。
        以技术之名:@雯籽雪 从实现角度可以理解成两张广告页,但是从产品角度第一张请求的算启动图
      • 9f94d02340f1:学习啦。谢谢!
        以技术之名:@JamesYea拿走,不谢!
      • 敢想敢做井底怪蛙:还没睡啊 我失眠了 半夜起来看简书 抚慰我的心灵
        以技术之名:@Anthony要幸福In杭州 我是睡到三点醒了一次:relieved:
      • 敢想敢做井底怪蛙:给你一枚好人卡
        以技术之名:@Anthony要幸福In杭州 拿走,不谢
      • 62dd3390b869:又打开了一条路
        以技术之名:@夜千星 :joy::joy::joy:
      • yunFeng: 这个是8之后的方法 可以获取launchstoryboard中的VC 之前就不可以了 以前做过这个需求 是可以获取到launchImage的 拿到之后再在launchImage上再添加一个image 或者View
        RadishHuang:@yunFeng 怎么动态拿到 launchImage ?
        以技术之名:@yunFeng 是的
      • Seeulater:其实就是广告页啊 。。。。。
        以技术之名:@Seeulater 其实好多app都是这种效果,我也是闲的无聊:joy::joy::joy::joy::joy:
        Seeulater:@Flying_Einstein 我之前做的时候看了一下百度云,以及支付宝的,能明显感觉到切换了一下图片,只是两张图片下半部分一样的,我断定他是动态请求的,但是并没有抓包去看:smile:,你还是很有求证精神的
        以技术之名:@Seeulater 也可以当做两次广告页,就是一个不成熟的思路
      • MrTrying:我是做android的哈!大图的话可以通过请求,保存到本地,下次启动的时候在显示
        Cyyyyyyyy:@Flying_Einstein 我觉得这是为了启动性能必须付出的代价
        MrTrying:@Flying_Einstein 确实是会有这种问题!这可以稍微优化一下,本地是有图片的,但是不是马上下显示,有一个几秒的定时器,这个时间内回去加载活动需要展示的图片,这个借口能会给出这个图片的是否需要本次加载,如果是时间内图片加载完成而且是本次展示的话就显示。其中有一个条件没有达成的话就下次了,而且图片还要判断是否过期
        以技术之名:@MrTrying 嗯,我也觉得这样比较合理,但是有一个问题,比如,用户好几天没用app,今天是五一,我想展示和五一相关的图片,如果用户今天只用一次的话,是看不到图片的
      • 辉的书:应用启动图片 时间一般不会太长,如果没有数据连接呢,第二张图片是不是必须是同步下载?
        以技术之名:@辉的书 我的思路是本地保存一张和启动图一样的图片,在没有数据链接的时候就当做第二张图片,如果有链接就用链接的图片
      • 国王or乞丐:不知道可否有dome 让参考下?
        杨__:@ios_Gzx demo。
        以技术之名:@ios_Gzx 可以的,文章最上方有链接

      本文标题:如何做到像百度云或者网易公开课一样动态更换APP启动图

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