改变iOS app的icon(iOS10.3)
改变iOS app的icon
(已被Cocoachina推荐到首页)
官方
iOS10.3新增了可以让开发者去更改app的icon,接下来看看怎么更改。
官方API给的东西很少,只是介绍了一个实例方法:
open func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Swift.Void)? = nil)
根据传入的参数可知,我们只需要传入备用icon名字即可,然后在回调里面拿到修改的结果,成功的话error为空,不成功则返回相应的错误信息(可以使用error!.localizedDescription来打印查看错误信息)。如果失败的话,alternateIconName属性不变。这里注意:
如果当期app使用的icon是备用的icon,那么这个属性的值就是当前icon的名字,这个名字是在Info.plist里面设置的名字,如果当前app展示的是主要(primary)的icon,那么这个值为nil。
这里需要注意两点:
- 当前设备的系统版本。这里的所有api都是10.3才能使用的。
- 当前app是否支持备用icon。使用supportsAlertnateIcons属性判断。只有为true的使用才能去更改。
API中还有一句话比较关键:
你必须在Info.plist里面使用CFBundleIcons声明当前app的primary和alternate icon。这里如果不了解可以往下看,先忽略。
具体的Info.plist里面的字段含义这里就不在一一说明,详情可了解这里。
总之官方API上面我只找到了这么多。然而给我的感觉反倒一脸懵逼,完全搞不懂下面的Info.plist怎么设置。因此有了下面的序文。
个人理解
在刚才的Info.plist key介绍里面,我们先看一下其他的小知识。
我们都知道在Info.plist里面有个Bundle display name,也就是设置app在桌面显示的名字。此时如果我们先不管这个key,我们继续在Info.plist里面添加CFBundleDisplayName,你会收到这样一个提示:
The key you entered is already present in the dictionary.do you want to replace the existing key/value pair?
但是看一下Info.plist字典中的key,并没有CFBundleDisplayName,替换后发现,原来它就是Bundle display name。也就是说,Info.plist里面的Key在Xcode中显示的并不是Key,而是Xcode name。如下图:

这个是从官方API上截的图,其实这些Key都有对应的Xcode name,也就是在Xcodes里面我们能看到的key。其实也很简单,如果你把Info.plist使用源码形式打开(右击—>Open as —>Source code),你就会发现这里写的key就是上面列出来的key。
先看看我在网上查资料设置的Info.plist:

这里的CFBundleIconFiles是备用icon的名字。下面的Primary Icon是默认的icon。源代码就是:

其中CFBundleIcons对应的就是Icon files(iOS 5),CFBundleIconFiles就是Primary Icon。
先看一下CFBundleAlternateIcons。这个CFBundleAlternateIcons key所对应的value在iOS里面是一个字典,例如:

每个字典的key是备用icon的名字,这个也是你传入到
IApplication.shared.setAlternateIconName(iconName) { (error) in
if (error != nil) {
self.aler(str: (error!.localizedDescription))
}else {
self.aler(str: "修改成功")
}
}
里面的iconName。其中的字典对应值解释如下:

CFBundleIconFiles:这个是一个String的数组,里面每个元素都是icon 的名字,你可以添加多个不同大小的icon来支持iPhone,iPad。
UIPrerenderedIcon:指定应用程序的图标是否包含闪光效果(shine effect),如果icon已经有这个效果,就把这个属性设置为YES来防止系统再次添加相同效果。如果设置为NO(默认值),iOS系统会自动添加这个效果。然而,我并没有测试出来这个效果!!
这里还要注意一下:Primary Icon的Item 0的name也可以不填写,苹果官方文档也没有具体说名字这个要怎么去填写,只是说如果你想使用CFBundlePrimaryIcon键值定义的icon,直接使用将setAlternateIconName的参数alternateIconName写成nil就行。在属性列表里面直接不填写就行(即把AppIcon60x60删掉)
自己新建一个项目实现
自己实现需要注意两个问题:
- Info.plist怎么设置?
- 备用图标icon放到哪里?
首先来设置Info.plist。
按照苹果官方的API说法,那就先在Info.plist里面添加CFBundleIcons。但是查看了一下Key和Xcode name对应的表格,CFBundleIcons对应的是None,那就直接添加CFBundleIcons吧。点击Information Property List后面的加号,输入CFBundleIcons,当点击Enter键的时候,你会惊奇发现:你添加的CFBundleIcons变成了Icon files(iOS 5)字典。看看CFBundleIcons的官方API:

根据英文意思可以知道:该key包含了所有app使用的icons信息。新建的是这样的:

可知默认的包含了CFBundlePrimaryIcon和UINewsstandIcon。里面没有CFBundleAlternateIcons,(我理解的应该是苹果不太想支持用户添加备选icon,所以才没有)。这里不过多介绍UINewsstandIcon了,它应该是在NewStand上展示的吧,不太清楚,想了解可以看API,里面介绍了。
现在把NewStand Icon删除,添加CFBundleAlternateIcons。添加后如图所示:

但是看官方API对CFBundleAlternateIcon的介绍里面,并没有UINewstandBindingType和UINewsstandBindingEdge,只有这个:

也就是官网所说的只有CFBundleIconFiles和UIPrerenderedIcon,那就删了多余的那两个UINewstandBindingType和UINewsstandBindingEdge。然后添加UIPrerenderedIcon:
。按照苹果的说法,把备用图标的名字放到Items0里面。我们先直接在左侧导航中加入两张图片:newicon@2x.png 和newicon@3x.png,一个120 * 120,一个180 * 180。
但是看到上图说的设置,跑起来运行代码:
@IBAction func changeToNewIconAction(_ sender: Any) {
if !checkSupportChangeIcon() {
return
}
if !UIApplication.shared.supportsAlternateIcons {
return
}
changeToIcon("newicon")
}
//MARK: check system version
func checkSupportChangeIcon() -> Bool {
let deviceVersion = UIDevice.current.systemVersion
if deviceVersion.contains("10.3") {
return true
}
return false
}
//MARK: change to icon message
func changeToIcon(_ iconName: String?) {
UIApplication.shared.setAlternateIconName(iconName) { (error) in
if (error != nil) {
self.aler(str: (error!.localizedDescription))
}else {
self.aler(str: "修改成功")
}
}
}
//MARK: alert message
func aler(str: String) {
let alert = UIAlertController.init(title: "提示", message: str, preferredStyle: .alert)
let okAction = UIAlertAction.init(title: "ok", style: .cancel) { (action: UIAlertAction) in
print("关闭弹出框")
}
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
结果却是:
The file doesn't exist
看了一下官方API对CFBundleAlternateIcons的介绍,里面有一句话:
In iOS, the value of the key is a dictionary. The key for each dictionary entry is the name of the alternate icon, which is also the string you pass to the setAlternateIconName:completionHandler: method of UIApplication when changing icons. The value for each key is a dictionary containing the keys in Table 5
意思是这个CFBundleAlternateIcons中的字典的key是备用icon的名字,因此需要这样修改:

也就是CFBundleAlternateIcons字典里面的key是备用icon的名字,然后以名字为key的字典里面又包含了CFBundleIconFiles和UIPrerenderedIcon。
这样设置之后再次运行你会发现成功更改了icon。
这样就成功地改变了icon。
关于Primary Icon,直接不用设置Icon files就好了,如果你想设置为默认的icon,就在setAlternateIconName里面传入nil就好了。这个时候Info.plist源码长这样:

在Property List里面,Primary Icon的Icon already includes gloss effects就是UIPrerenderedIcon,它的设置为false。(这里的光泽效果也是没有测试出来有什么不一样)
接下来看看备用icon是在哪里放着呢?
开始的时候直接放到这里:

发现是OK的,可以正常显示。
那么放到Assets.xcassets里面呢?放到Bundle里面呢?接下来将每个case都进行测试:
- 放到Assets.xcassets里面。新建一个普通的Image set,然后将图片放到里面,效果如图所示:

经过测试发现,这样放置是无法正常改变appicon的。但是运行结果没有任何错误,而且系统提示里面加载的也是新的app icon:

- 放到Assets.xcassets里面,并且新建的icon,如图:

运行依然设置不成功。没有错误提示 - 放到一个新建的Bundle里面。如图所示:。

运行结果依然是没有成功更改。没有错误提示。
所以经过测试,发现只有放到导航里面的图片才可以更改成功。在苹果qa里面看到过一个场景,他们是直接在导航新建了一个文件夹,然后将图片放到里面,然后使用。这里也推荐建立文件夹放入图片,然后使用
另外,关于icon大小,可以参见这里。
最后告诉大家一个不使用Asset来配置Icon的方法:直接在Info.plist下面这样写:

这个是通用的,可以直接设置iPhone和iPad的icon。其实这里也是想告诉大家:如何在CFBundleIconFiles里面去添加图片数组:
<key>CFBundleIconFiles</key>
<array>
<string>Icon-Small</string>
<string>Icon-Small-40</string>
<string>Icon-Small-50</string>
<string>Icon</string>
<string>Icon-60</string>
<string>Icon-72</string>
</array>
备注
- 如果有什么疑问欢迎留言提问。或直接加群:206613455
- 源码地址:https://github.com/ScottZg/iOSChangeAppIcon
改变iOS app的icon(iOS10.3)的更多相关文章
- 改变iOS app的icon(iOS10.3)
原文 改变iOS app的icon官方iOS10.3新增了可以让开发者去更改app的icon,接下来看看怎么更改.官方API给的东西很少,只是介绍了一个实例方法: 1 open func setAlt ...
- 17.iOS App设置icon,启动图,App名称的方法
icon:选择Assets-->AppIcon-->将各种尺寸的icon拖拽到相应的框中. APP名称:选择info-->Bundle name,修改APP名字. 启动图: 首先点击 ...
- 在iOS App的图标上显示版本信息
最近读到一篇文章(http://www.merowing.info/2013/03/overlaying-application-version-on-top-of-your-icon/)介绍了一种非 ...
- [摘抄]iOS App icon、启动页、图标规范
以下内容都是我在做App时通过自己的经验和精品的分析得来的,希望会帮助到你.但是有时个别情况也要个别分析,要活学活用. 一. App Icon 在设计iOS App Icon时,设计师不需要切圆角, ...
- Asset Catalog Help (五)---Migrating an iOS App Icon Set or Launch Image Set
Migrating an iOS App Icon Set or Launch Image Set Simplify image management by moving existing app i ...
- Asset Catalog Help (四)---Adding an iOS App Icon Set or Launch Image Set
Adding an iOS App Icon Set or Launch Image Set Organize different resolutions of your app icons and ...
- iOS 在iphoneX上运行的app没有icon图标,在其他手机上有图标
今天朋友问了一个问题,在iPhoneX上运行的app没有icon图标,在其他手机上有图标. 一开始我以为是没放iPhoneX的图标,后面朋友解决了,告诉了我原因,这里记录下吧: 原因: 图标格式问题, ...
- (转)在iOS中使用icon font
http://ued.taobao.org/blog/?p=8579 在开发阿里数据iOS版客户端的时候,由于项目进度很紧,项目里的所有图标都是用最平常的背景图片方案来实现.而为了要兼容普通屏与Ret ...
- 在iOS中使用icon font
博文转载至 http://www.cocoachina.com/industry/20131111/7327.html 在开发阿里数据iOS版客户端的时候,由于项目进度很紧,项目里的所有图标都是用最平 ...
随机推荐
- GridControl基础设置(一)
1. 如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 2. 如何新增一条记录 (1).gridView.Ad ...
- 中间自适应,左右定宽的两种经典布局 ---- 圣杯布局 VS 双飞翼布局
一.引子 最近学了些js框架,小有充实感,又深知如此节奏的前提需得基础扎实,于是回头想将原生CSS和Javascript回顾总结一番,先从CSS起,能集中它的就在基础的布局上,便查阅了相关资料,将布局 ...
- android学习1——LinearLayout
用linearLayout,上面放4个按钮,不作任何设置.xml文件内容如下: <?xml version="1.0" encoding="utf-8"? ...
- 关于jquery中封装函数如何传递当前元素的问题
需要对页面上一组元素进行ajax操作 <div id="aid"></div> <div id="aid"></div ...
- burp插件开发
最近这几天在写burp的插件,有一些写burp插件的流程和误区想跟大家分享一下: 第一步,打开burpsuit,打开extender页面,并将burp中自带的api代码导出,方便后续的代码开发: 第二 ...
- 操作符、语句、函数——Javascript高级程序设计
1.操作符 一元操作符:++.--放在变量前后的区别,+.—表示正负 位操作符:64位存储.32位计算,对NOT.AND.OR.XOR.<<.>>.>>>的掌 ...
- 【转】Jqgrid学习之数据
jqGrid可支持的数据类型:xml.json.jsonp.local or clientSide.xmlstring.jsonstring .script.function (…). Json数据 ...
- 每天一个linux命令(48)--ln命令
ln是Linux中又一个非常重要的命令,它的功能是为某个文件在另外一个位置建立一个同步的链接,当我们需要在不同的目录,用到相同的文件时,我们不需要在每个需要的目录下都放一个相同的文件,我们只要在某个固 ...
- Token在android中的使用
首先Token是一个怎么样的东西,Token存在的意义又在哪里?学过php或是其他web开发的人都知道一个东西叫session和cookie,这些东西可以在服务器或是本地保存一些东西,比如说登录状态, ...
- Redis 安装与简单使用
安装 Redis 一般系统都会有软件管理工具,但是通常版本都不会太新,况且 Redis 的安装很简单,因此下面使用源码的安装方式. 下载源码 wget http://download.redis.io ...