- 在iOS10.3系统发布之前, 众所周知, 在App Store上架的APP如果要更换Icon图, 只能更新版本替换;
- 这次苹果却在iOS10.3系统中加入了了更换应用图标的新功能,当应用安装后,开发者可以为应用提供多个应用图标选择。
- 用户可以自由的在这些图标之间切换,并及时生效。
- 这是因为 10.3 里引入了一个新的 API,它允许在 App 运行的时候,通过代码为 app 更换 icon
项目配置
- 虽然提供了更换的功能,但更换的 icon 是有限制的
- 它只能更换项目中提前添加配置好的Icon图
具体可参考demo–github项目地址
这里先看个效果
备选Icon
- 首先你需要将备选的Icon图添加到项目中,
- 注意:
- 图片不要放到
Assets.xcassets
, 而应该直接放到工程中, 不然可能导致更换Icon时, 找不到图片, 更换失败 - 在
info.plist
的配置中,图片的文件名应该尽量不带 @2x/@3x 后缀扩展名,而让它自动选择
- 图片不要放到
配置info.plist
文件
- 在
info.plist
文件中,添加对应的CFBundleAlternateIcons
的信息 - 这里也可以查看官方的相关介绍
Source Code
添加方式如下
1 | <key>CFBundleAlternateIcons</key> |
- 注意事项:
- 虽然文档中写着
「You must declare your app's primary and alternate icons using the CFBundleIcons key of your app's Info.plist file. 」
,但经测试,CFBundlePrimaryIcon
可以省略掉。在工程配置App Icons and Launch Image
-App Icons Source
中使用asset catalog
(默认配置),删除CFBundlePrimaryIcon
的配置也是没有问题的。 - 省略这个配置的好处是,避免处理
App icon
的尺寸。现在的工程中,大家一般都使用asset catalog
进行 icon 的配置,而一个 icon 对应有很多尺寸的文件。省略CFBundlePrimaryIcon
就可以沿用Asset
中的配置。 - 如果想设置回默认 icon,在
setAlternateIconName
中传入 nil 即可
- 虽然文档中写着
API调用
下面我们看一下系统提供的三个API, 这里产看官方文档
1 | var supportsAlternateIcons: Bool |
具体的实现代码:
1 | if |
消除alert弹窗
- 动态更换App图标会有弹框, 有时候这个弹框看上去可能会很别扭, 但是这个弹框是系统直接调用弹出的, 我们又如何消除呢
- 通过层级关系可以看到这个弹框就是一个
UIAlertController
, 并且是通过presentViewController:animated:completion:
方法弹出的 - 所以可以考虑使用
runtime
, 拦截并替换该方法, 让更换icon的时候, 不弹 - 下面看一下具体代码:
1 | extension NoAlertChangeViewController { |
- 这里用到了
DispatchQueue.once
, 这个once
是我对DispatchQueue
加了一个扩展 - 在Swift4.0以后,
static dispatch_once_t onceToken;
这个已经不能用了 - 关于这方面的详细介绍, 大家可以看看我的这篇文章–升级Swift4.0遇到的坑
-
支持不同尺寸的Icon
- 一个标准的Icon图集, 需要十几种尺寸, 比如: 20, 29, 40, 60等
- 对于
info.plist
中的每个icon
配置,CFBundleIconFiles
的值是一个数组,我们可以在其中填入这十几种规格的图片名称。经测试:- 文件的命名没有强制的规则,可以随意取,
- 数组中的文件名也不关心先后顺序。
- 总之把对应的文件名填进去即可,它会自动选择合适分辨率的文件(比如在 setting 中显示 icon 时,它会找到提供的数组中分辨率为 29pt 的那个文件)。
- 具体相关官方文档可参考, 官方介绍
- 首先, 针对不同的尺寸, 我们要有不同的命名, 具体参考下图
- 文件扩展名,如@2x,@3x,要么统一不写,那么系统会自动寻找合适的尺寸。
- 要写就需要把每张icon的扩展名写上,和上图的格式一样
- 代码中调用图片名, 更不需要加上尺寸:
1 | if |
- 具体可参考demo–github项目地址