改變iOS app的icon
官方
iOS10.3新增了可以讓開發(fā)者去更改app的icon,接下來看看怎么更改锭部。
官方API給的東西很少,只是介紹了一個(gè)實(shí)例方法:
open func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Swift.Void)? = nil)
根據(jù)傳入的參數(shù)可知恐锦,我們只需要傳入備用icon名字即可融击,然后在回調(diào)里面拿到修改的結(jié)果,成功的話error為空吓歇,不成功則返回相應(yīng)的錯(cuò)誤信息(可以使用error!.localizedDescription來打印查看錯(cuò)誤信息)孽水。如果失敗的話,alternateIconName屬性不變城看。這里注意:
如果當(dāng)期app使用的icon是備用的icon女气,那么這個(gè)屬性的值就是當(dāng)前icon的名字,這個(gè)名字是在Info.plist里面設(shè)置的名字测柠,如果當(dāng)前app展示的是主要(primary)的icon炼鞠,那么這個(gè)值為nil。
這里需要注意兩點(diǎn):
- 當(dāng)前設(shè)備的系統(tǒng)版本轰胁。這里的所有api都是10.3才能使用的谒主。
- 當(dāng)前app是否支持備用icon。使用supportsAlertnateIcons屬性判斷赃阀。只有為true的使用才能去更改霎肯。
API中還有一句話比較關(guān)鍵:
你必須在Info.plist里面使用CFBundleIcons聲明當(dāng)前app的primary和alternate icon。這里如果不了解可以往下看榛斯,先忽略观游。
具體的Info.plist里面的字段含義這里就不在一一說明,詳情可了解這里肖抱。
總之官方API上面我只找到了這么多备典。然而給我的感覺反倒一臉懵逼咪辱,完全搞不懂下面的Info.plist怎么設(shè)置饲嗽。因此有了下面的序文。
個(gè)人理解
在剛才的Info.plist key介紹里面,我們先看一下其他的小知識(shí)芳肌。
我們都知道在Info.plist里面有個(gè)Bundle display name瘦棋,也就是設(shè)置app在桌面顯示的名字被廓。此時(shí)如果我們先不管這個(gè)key党觅,我們繼續(xù)在Info.plist里面添加CFBundleDisplayName,你會(huì)收到這樣一個(gè)提示:
The key you entered is already present in the dictionary.do you want to replace the existing key/value pair?
但是看一下Info.plist字典中的key倚喂,并沒有CFBundleDisplayName每篷,替換后發(fā)現(xiàn),原來它就是Bundle display name端圈。也就是說焦读,Info.plist里面的Key在Xcode中顯示的并不是Key,而是Xcode name舱权。如下圖:
這個(gè)是從官方API上截的圖矗晃,其實(shí)這些Key都有對應(yīng)的Xcode name,也就是在Xcodes里面我們能看到的key宴倍。其實(shí)也很簡單张症,如果你把Info.plist使用源碼形式打開(右擊—>Open as —>Source code),你就會(huì)發(fā)現(xiàn)這里寫的key就是上面列出來的key。
先看看我在網(wǎng)上查資料設(shè)置的Info.plist:
這里的CFBundleIconFiles是備用icon的名字鸵贬。下面的Primary Icon是默認(rèn)的icon俗他。源代碼就是:
其中CFBundleIcons對應(yīng)的就是Icon files(iOS 5),CFBundleIconFiles就是Primary Icon阔逼。
先看一下CFBundleAlternateIcons兆衅。這個(gè)CFBundleAlternateIcons key所對應(yīng)的value在iOS里面是一個(gè)字典,例如:
每個(gè)字典的key是備用icon的名字颜价,這個(gè)也是你傳入到
IApplication.shared.setAlternateIconName(iconName) { (error) in
if (error != nil) {
self.aler(str: (error!.localizedDescription))
}else {
self.aler(str: "修改成功")
}
}
里面的iconName涯保。其中的字典對應(yīng)值解釋如下:
CFBundleIconFiles:這個(gè)是一個(gè)String的數(shù)組,里面每個(gè)元素都是icon 的名字周伦,你可以添加多個(gè)不同大小的icon來支持iPhone,iPad。
UIPrerenderedIcon:指定應(yīng)用程序的圖標(biāo)是否包含閃光效果(shine effect),如果icon已經(jīng)有這個(gè)效果未荒,就把這個(gè)屬性設(shè)置為YES來防止系統(tǒng)再次添加相同效果专挪。如果設(shè)置為NO(默認(rèn)值),iOS系統(tǒng)會(huì)自動(dòng)添加這個(gè)效果片排。然而寨腔,我并沒有測試出來這個(gè)效果!!
這里還要注意一下:Primary Icon的Item 0的name也可以不填寫,蘋果官方文檔也沒有具體說名字這個(gè)要怎么去填寫率寡,只是說如果你想使用CFBundlePrimaryIcon鍵值定義的icon迫卢,直接使用將setAlternateIconName的參數(shù)alternateIconName寫成nil就行。在屬性列表里面直接不填寫就行(即把AppIcon60x60刪掉)
自己新建一個(gè)項(xiàng)目實(shí)現(xiàn)
自己實(shí)現(xiàn)需要注意兩個(gè)問題:
- Info.plist怎么設(shè)置冶共?
- 備用圖標(biāo)icon放到哪里乾蛤?
首先來設(shè)置Info.plist每界。
按照蘋果官方的API說法,那就先在Info.plist里面添加CFBundleIcons家卖。但是查看了一下Key和Xcode name對應(yīng)的表格眨层,CFBundleIcons對應(yīng)的是None,那就直接添加CFBundleIcons吧上荡。點(diǎn)擊Information Property List后面的加號(hào)趴樱,輸入CFBundleIcons,當(dāng)點(diǎn)擊Enter鍵的時(shí)候酪捡,你會(huì)驚奇發(fā)現(xiàn):你添加的CFBundleIcons變成了Icon files(iOS 5)字典叁征。看看CFBundleIcons的官方API:
根據(jù)英文意思可以知道:該key包含了所有app使用的icons信息逛薇。新建的是這樣的:
可知默認(rèn)的包含了CFBundlePrimaryIcon和UINewsstandIcon捺疼。里面沒有CFBundleAlternateIcons,(我理解的應(yīng)該是蘋果不太想支持用戶添加備選icon金刁,所以才沒有)帅涂。這里不過多介紹UINewsstandIcon了,它應(yīng)該是在NewStand上展示的吧尤蛮,不太清楚媳友,想了解可以看API,里面介紹了产捞。
現(xiàn)在把NewStand Icon刪除醇锚,添加CFBundleAlternateIcons。添加后如圖所示:
但是看官方API對CFBundleAlternateIcon的介紹里面坯临,并沒有UINewstandBindingType和UINewsstandBindingEdge焊唬,只有這個(gè):
也就是官網(wǎng)所說的只有CFBundleIconFiles和UIPrerenderedIcon,那就刪了多余的那兩個(gè)UINewstandBindingType和UINewsstandBindingEdge看靠。然后添加UIPrerenderedIcon:
但是看到上圖說的設(shè)置婿滓,跑起來運(yùn)行代碼:
@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("關(guān)閉彈出框")
}
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
結(jié)果卻是:
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
意思是這個(gè)CFBundleAlternateIcons中的字典的key是備用icon的名字粥喜,因此需要這樣修改:
也就是CFBundleAlternateIcons字典里面的key是備用icon的名字凸主,然后以名字為key的字典里面又包含了CFBundleIconFiles和UIPrerenderedIcon。
這樣設(shè)置之后再次運(yùn)行你會(huì)發(fā)現(xiàn)成功更改了icon额湘。
這樣就成功地改變了icon卿吐。
關(guān)于Primary Icon旁舰,直接不用設(shè)置Icon files就好了,如果你想設(shè)置為默認(rèn)的icon但两,就在setAlternateIconName里面?zhèn)魅雗il就好了鬓梅。這個(gè)時(shí)候Info.plist源碼長這樣:
在Property List里面,Primary Icon的Icon already includes gloss effects就是UIPrerenderedIcon谨湘,它的設(shè)置為false绽快。(這里的光澤效果也是沒有測試出來有什么不一樣)
接下來看看備用icon是在哪里放著呢?
開始的時(shí)候直接放到這里:
發(fā)現(xiàn)是OK的紧阔,可以正常顯示坊罢。
那么放到Assets.xcassets里面呢?放到Bundle里面呢擅耽?接下來將每個(gè)case都進(jìn)行測試:
-
放到Assets.xcassets里面活孩。新建一個(gè)普通的Image set,然后將圖片放到里面乖仇,效果如圖所示:
經(jīng)過測試發(fā)現(xiàn)憾儒,這樣放置是無法正常改變appicon的。但是運(yùn)行結(jié)果沒有任何錯(cuò)誤乃沙,而且系統(tǒng)提示里面加載的也是新的app icon:
-
放到Assets.xcassets里面起趾,并且新建的icon,如圖:
運(yùn)行依然設(shè)置不成功警儒。沒有錯(cuò)誤提示
-
放到一個(gè)新建的Bundle里面训裆。如圖所示:。
運(yùn)行結(jié)果依然是沒有成功更改蜀铲。沒有錯(cuò)誤提示边琉。
所以經(jīng)過測試,發(fā)現(xiàn)只有放到導(dǎo)航里面的圖片才可以更改成功记劝。在蘋果qa里面看到過一個(gè)場景变姨,他們是直接在導(dǎo)航新建了一個(gè)文件夾,然后將圖片放到里面厌丑,然后使用钳恕。這里也推薦建立文件夾放入圖片,然后使用
另外蹄衷,關(guān)于icon大小,可以參見這里厘肮。
最后告訴大家一個(gè)不使用Asset來配置Icon的方法:直接在Info.plist下面這樣寫:
這個(gè)是通用的愧口,可以直接設(shè)置iPhone和iPad的icon。其實(shí)這里也是想告訴大家:如何在CFBundleIconFiles里面去添加圖片數(shù)組:
<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>
備注
- 如果有什么疑問歡迎留言提問类茂∷J簦或直接加群:206613455
2.源碼地址:https://github.com/ScottZg/iOSChangeAppIcon