原文

改变iOS app的icon
官方
iOS10.3新增了可以让开发者去更改app的icon,接下来看看怎么更改。
官方API给的东西很少,只是介绍了一个实例方法:

1
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,你会收到这样一个提示:

1
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的名字,这个也是你传入到

1
2
3
4
5
6
7
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。
但是看到上图说的设置,跑起来运行代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@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)
}

结果却是:

1
The file doesn't exist

看了一下官方API对CFBundleAlternateIcons的介绍,里面有一句话:

1
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里面去添加图片数组:

1
CFBundleIconFiles                          Icon-Small               Icon-Small-40               Icon-Small-50               Icon               Icon-60               Icon-72
 
 

改变iOS app的icon(iOS10.3)的更多相关文章

  1. 改变iOS app的icon(iOS10.3)

    改变iOS app的icon 官方 iOS10.3新增了可以让开发者去更改app的icon,接下来看看怎么更改. 官方API给的东西很少,只是介绍了一个实例方法: open func setAlter ...

  2. 17.iOS App设置icon,启动图,App名称的方法

    icon:选择Assets-->AppIcon-->将各种尺寸的icon拖拽到相应的框中. APP名称:选择info-->Bundle name,修改APP名字. 启动图: 首先点击 ...

  3. 在iOS App的图标上显示版本信息

    最近读到一篇文章(http://www.merowing.info/2013/03/overlaying-application-version-on-top-of-your-icon/)介绍了一种非 ...

  4. [摘抄]iOS App icon、启动页、图标规范

    以下内容都是我在做App时通过自己的经验和精品的分析得来的,希望会帮助到你.但是有时个别情况也要个别分析,要活学活用. 一. App  Icon 在设计iOS App Icon时,设计师不需要切圆角, ...

  5. 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 ...

  6. 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 ...

  7. iOS 在iphoneX上运行的app没有icon图标,在其他手机上有图标

    今天朋友问了一个问题,在iPhoneX上运行的app没有icon图标,在其他手机上有图标. 一开始我以为是没放iPhoneX的图标,后面朋友解决了,告诉了我原因,这里记录下吧: 原因: 图标格式问题, ...

  8. (转)在iOS中使用icon font

    http://ued.taobao.org/blog/?p=8579 在开发阿里数据iOS版客户端的时候,由于项目进度很紧,项目里的所有图标都是用最平常的背景图片方案来实现.而为了要兼容普通屏与Ret ...

  9. 在iOS中使用icon font

    博文转载至 http://www.cocoachina.com/industry/20131111/7327.html 在开发阿里数据iOS版客户端的时候,由于项目进度很紧,项目里的所有图标都是用最平 ...

随机推荐

  1. 数据库:MySQL索引背后的数据结构及算法原理【转】

    原文:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话 ...

  2. svn使用技巧一:更新、提交、资源库同步之间区别

    提交:是用本地文件覆盖服务器的文件,只有提交会导致服务器上发生变化 更新:只是把服务器上最新版本下载到客户端,规则如下: 1.如果你本地的某个文件没有修改过,而服务器上的这个文件别人已经提交过新版本, ...

  3. HtmlHelper(辅助产生HTML之用)

    弱类型: 1.使用HTML辅助方法输出超链接 (1)在View中输出ASP.NET MVC的超链接通常会用Html.ActionLink辅助方法,该方法用于产生文字链接,其文字部分会自动进行HTML编 ...

  4. 10-14C#基础--语句(switch....case和for...循环)

    10-14C#基础--语句(2) 一.课前作业:“跟电脑猜拳” 二.switch(定义的变量,参数值)......case.... 注:switch...case大多用于值类型的判断,这里不同于if表 ...

  5. ORA-04098 trigger 'DBBJ.DB_EV_ALTER_ST_METADATA' is invalid and failed re-validation

    转自:https://blog.csdn.net/dragoo1/article/details/9411105 ORA-04098: trigger 'DBBJ.DB_EV_ALTER_ST_MET ...

  6. Shell编程进阶 2.0 shell中断继续退出

    break    continue   exit break 结束本次for循环 写个for循环脚本 vim for2.sh #!/bin/bash ## 5` do echo $i ] then b ...

  7. rm 删除文件或目录

    rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉.对于链接文件,只是删除整个链接文件,而原有文件保持不变. 注意:使用rm命令要格外小心.因为一旦 ...

  8. 全局事务/分布式事务 (Global Transaction/ A distributed transaction)之我见

    这里参考的是Oracle对于XA的支持,其他的应该雷同吧... 1个分布式事务由多个行为在不同的数据库上执行,1个分布式事务的执行成功意味着相关数据库上的行为执行均成功.“XA协定”(http://w ...

  9. Linux 大页面使用与实现简介(转)

    引言 随着计算需求规模的不断增大,应用程序对内存的需求也越来越大.为了实现虚拟内存管理机制,操作系统对内存实行分页管理.自内存“分页机制”提出之始,内存页面的默认大小便被设置为 4096 字节(4KB ...

  10. Linux bc命令

    一.简介 GNU bc是一款基于命令行的计算器程序,支持高精度数字和多种数值类型(例如二进制.十进制.十六进制)的输入输出. 二.实例 http://www.linuxidc.com/Linux/20 ...