开发者社区> 韩俊强> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

iOS新特性: iOS10.3教你如何动态更换APP图标?(后台切换) 韩俊强的博客

简介: 1、iOS 10.3 开放了更换 app 图标的 API,核心方法是下面这个: [[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^( }]; 这是官方文档,但是你还需要在 info.plist 里面填一些东西才能让它起作用,这部分官方注释内容在这里。
+关注继续查看


1、iOS 10.3 开放了更换 app 图标的 API,核心方法是下面这个:

[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(

 }];

这是官方文档,但是你还需要在 info.plist 里面填一些东西才能让它起作用,这部分官方注释内容在这里



2、 info.plist 如何填写呢?一时可能搞不清楚如何操作,下面做个实例:







3、具体如下:



<key>CFBundleIcons</key>
    <dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>newIcon</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>newIcon</string>
                </array>
                <key>UIPrerenderedIcon</key>
                <false/>
            </dict>
        </dict>
        <key>CFBundlePrimaryIcon</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <string>Icon60X60</string>
            </array>
        </dict>
    </dict>

如图,Primary Icon 字段写为 Icon60X60 是因为这里 xcassets 里面我只导入了 60pt@2x 和 60pt@3x 的图片资源,这里选为 60 是因为对于 iPhone,60pt 的图片资源图标所需最高质量,更低分辨率的版本系统会自动压缩以展示。

newIcon 是我的用于替换原生图标的图片资源。文件名需要和 info.plist 中保持一致(注意 info.plist 中用到了两次 "newIcon"),同时这也是你在代码中设置图标时,需要给 API 传入的参数。同样是 60pt@2x 和 60pt@3x 的图片资源,文件不通过 Assets.xcassets 添加进来,而是直接放到目录中。

如果你需要支持 iPad,建议这里使用 83.5pt(iPad Pro)的图片资源。另外还有些其他关于在 iPad 上替换图标的注意事项,在这里有说明,注意我们这里在 info.plist 里面所用的 key 是 CFBundleIcons,还有另外一个 key 是 CFBundleIcons~ipad

4、替换图标部分的代码:

- (void)changeAppIcon
{
    if ([UIApplication sharedApplication].supportsAlternateIcons) {
        NSLog(@"you can change this app's icon");
    }else{
        NSLog(@"you can not change this app's icon");
        return;
    }
    
    NSString *iconName = [[UIApplication sharedApplication] alternateIconName];
    
    if (iconName) {
        // change to primary icon
        [[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"set icon error: %@",error);
            }
            NSLog(@"The alternate icon's name is %@",iconName);
        }];
    }else{
        // change to alterante icon
        [[UIApplication sharedApplication] setAlternateIconName:@"newIcon" completionHandler:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"set icon error: %@",error);
            }
            NSLog(@"The alternate icon's name is %@",iconName);
        }];
    }
}

5、最终效果如下:



优化:

很多人就说了,每次都要弹框修改多费劲啊,能不能优化在后台切换icon呢?我的答案是:能!

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self runtimeReplaceAlert];
}

// 利用runtime来替换展现弹出框的方法
- (void)runtimeReplaceAlert
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
        Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(ox_presentViewController:animated:completion:));
        // 交换方法实现
        method_exchangeImplementations(presentM, presentSwizzlingM);
    });
}

// 自己的替换展示弹出框的方法
- (void)ox_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    
    if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
        NSLog(@"title : %@",((UIAlertController *)viewControllerToPresent).title);
        NSLog(@"message : %@",((UIAlertController *)viewControllerToPresent).message);
        
        // 换图标时的提示框的title和message都是nil,由此可特殊处理
        UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
        if (alertController.title == nil && alertController.message == nil) { // 是换图标的提示
            return;
        } else {// 其他提示还是正常处理
            [self ox_presentViewController:viewControllerToPresent animated:flag completion:completion];
            return;
        }
    }
    
    [self ox_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
优化后的效果如下:




手机加iOS开发者交流QQ群: 446310206

Demo:GitHub  喜欢记得star一下哦!



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[leetcode]剑指 Offer 32 - III. 从上到下打印二叉树 III BFS二叉树
二叉树简单遍历 将访问的序列存入 vector,对于每一层交替从左向右从右向左我们可以设置一个变量flag来决定方向 用 pre 表示上一层的节点数量,用 cnt 求得上本层的节点数量,在遍历的时候遇到一个点就将 pre−1,如果说 pre 为0了,那么就说明上一层的节点已经访问完毕,然后将在该过程中访问得到 val 的 vector 集合存入答案,根据 flag 的值进行判断是否需要逆置
11 0
阿里云oss如何被挂载到阿里云ecs上,实现内网高速数据备份与共享
ossfs能让您在Linux系统中,将对象存储OSS的存储空间(Bucket)挂载到本地文件系统中,您能够像操作本地文件一样操作OSS的对象(Object),实现数据的共享。
443 0
数据湖实操讲解【 AI 训练加速】第十八讲:Fluid + JindoFS 对海量小文件的训练加速
数据湖 JindoFS+OSS 实操干货 36讲 每周二16点准时直播! 扫文章底部二维码入钉群,线上准时观看~ Github链接: https://github.com/aliyun/alibabacloud-jindofs
194 0
产品百科 | 如何在 iOS 模拟器上安装阿里云短视频 SDK
短视频 SDK 在 IOS 模拟器上安装和使用的方法
152 0
云上数据安全实践:使用 KMS 一键保护 ECS 工作负载
当您的 ECS 工作负载用于处理生产数据时,它通常会接触到您的关键业务机密、您的客户隐私信息或者关键系统凭证,因此需要对工作负载进行保护防范信息泄露。阿里云 KMS 支持您通过一键加密的方式,围绕工作负载,保护计算环境中产生的临时和持久数据,满足您对数据安全、隐私以及合规的要求。 对负责运维和安全的团队来说,加密 ECS 工作负载的资源是 DevOps 研发模式下,简单而有效的安全兜底方案。
720 0
iOS开发中 关于阿里云服务器的使用与安全策略 韩俊强的博客
使用背景:         云服务已经很多年了,早期没能加入使用云大军中的一员,后来后悔莫及。2015年记得当时没办法租用的虚拟主机三天两天挂了,导致我认认真真的考虑了一次,觉得还是要使用云服务器! 从免费的主机屋学习版到各种虚拟机的实验,再到之前是用300元左右买的别人的虚拟主机,空间有几G,感觉还行,正好又值他们搞活动,买两年送一年!预存还有返还!心动了,就没有任何考虑就预存了一千块! 开始的几个月感觉还行,速度什么的还过得去,就没去管网站的事了。
1778 0
我的2016 “CSDN博客之星” 韩俊强的博客
2016年12月31日         时间如白驹过隙,转眼间2016年的尾巴快要抓不住了。总结一下这一年的自我价值和工作业绩,不知该如何下笔,因为不知道自己奋斗的是否还是年初的目标。大家都知道2016雾霾一直驱之不散,作为开发人员,这一年也是在紧迫的情景下进行的,时而被各种裁员新闻所忧虑,时而被“996”所困扰,但是我们在成长,不能被外界所困。
911 0
iOS中 百度地图详解 韩俊强的博文
需要准备工作按照下图引进类库 需要添加 添加的两个字符串为:NSLocationWhenInUseUsageDescription  /  NSLocationAlwaysUsageDescription 默认定位设置: 设置工作准备完毕上代码: 指示根视图: ...
593 0
+关注
韩俊强
高级软件开发工程师, 博客专家, 阿里云MVP, CSDN十大博客之星, 十佳专栏 。
494
文章
7
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载