動態更新App的圖示(AppIcon)
序言
隨著時代的進步,人的生活多元化。一些公司的 App 也隨著人的生活改變而進行適和情景的變化。比如,本公司的 App 在四月時是本公司成立 4 週年的生日,那就想在本公司 App 的 Icon 上新增一個聖誕帽。第一種方法: 在 App 的工程中,替換原始的 AppIcon ,再提交 AppStore 進行稽核。這種方法不說麻煩,而且耗費時間長。第二種:在 App 中動態更新 AppIcon 。 這種方法直接、快速、適合即時應用。
1、本部落格介紹方法實現的效果圖如下
2、 重點知識點的介紹
@interface UIApplication (UIAlternateApplicationIcons )
// If false, alternate icons are not supported for the current process.
@property (readonly, nonatomic) BOOL supportsAlternateIcons NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2));
// Pass `nil` to use the primary application icon. The completion handler will be invoked asynchronously on an arbitrary background queue; be sure to dispatch back to the main queue before doing any further UI work.
- (void)setAlternateIconName:(nullable NSString *)alternateIconName completionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2));
// If `nil`, the primary application icon is being used.
@property (nullable, readonly, nonatomic) NSString *alternateIconName NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2));
@end
1 / supportsAlternateIcons 函式
該函式是判斷裝置是否支援備用 AppIcon 的功能。該功能的使用條件是裝置的系統必須是 iOS 10.3 以上的版本。
2 / alternateIconName 引數
該引數是一個只讀屬性的引數,如果該引數為 nil 時,那App 就會使用預設的AppIcon 。否則,App 使用的是備用AppIcon ,那麼 alternateIconName 獲得的結果就是App 正在使用的備用AppIcon的名子。
3 / setAlternateIconName: completionHandler: 函式
該函式是執行AppIcon 圖示替換的功能。在進行替換時 App 的系統會彈出一個提示讓你確定是否變更AppIcon 。如果,要自動變更App 的 Icon ,那麼這個提示就不能出現。對於如何去掉這個提示,後面介紹。
3、使用備用AppIcon需要在工程的 info.plist 檔案中進行配置,配置如下:
1、新增流程
- 我們在工程的 Info.plist 檔案中新增 Icon files(iOS 5) 的 key 。該 key 的型別(Type)為 Dictionary 。
- Icon files(iOS 5) 對應的字典,包含 2 個物件分別是: Primary Icon 、Newsstand Icon。 這兩個物件的型別也是 * Dictionary* 。
- 我們要使用備用的AppIcon ,那麼我們就要在 Icon files(iOS 5) 對應的字典中,新增一個物件 CFBundleAlternateIcons 物件,該物件的型別是字典(Dictionary)。
- 我們在CFBundleAlternateIcons 物件中新增備用*AppIcon 的影象物件。如上圖 Icon1、Icon2 所示,這兩個物件的型別也是字典。
- 我們要在新增的AppIcon物件中在新增一個 CFBundleIconFiles 的物件,該物件的型別是陣列(Array)。
- 在CFBundleIconFiles 的物件中新增AppIcon 的影象檔名字為元素,該元素的型別是 String,以便後期使用。
2、引數介紹
- Primary Icon 是預設 AppIcon 的物件。該物件包含 *Icon already includes gloss effects 、Icon files 兩個物件。 *Icon already includes gloss effects 是一個布林型別,它表示AppIcon 是否是高光狀態。Icon files 是一個數組物件,它包含預設的AppIcons 的檔名字物件,物件型別是字串(String)。
- CFBundleAlternateIcons 備用AppIcon 可能有好幾個,那麼CFBundleAlternateIcons 包含的物件就不只一個。我們介紹其中一個例如 Icon1 包含 CFBundleIconFiles 一個存放AppIcon 影象的陣列。陣列內是各個AppIcon 檔案的名字。
- Newsstand Icon 這是報刊類 Newsstand App 的圖示設定。該物件包含 Binding edge、Icon files、Binding type 三個物件。Binding edge 是一個字串物件,它的作用是設定Newsstand Icon 的位置,可選型別有 left、right、bottom 。Icon files 是一個數組物件,它裡面存放影象的檔名字。Binding type 是設定Newsstand Icon 歸屬的型別,型別可選有 Magazine 、 *Newspaper。
4、 核心程式碼
#pragma mark Change 'AppIcon'
-(void) changeAppIcon:(NSString *) iconName {
// TODO: Get the App itself
UIApplication * application = [UIApplication sharedApplication];
// TODO: Determine whether the device supports' AlternateIcons'
/**
* AlternateIcons : 擴充套件備用圖示。
* 使用條件: ios10.3 以上的裝置
*/
if ([application supportsAlternateIcons]) {
// Change the 'AppIcon'
[application setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
// Change the abnormal result of 'AppIcon'
NSLog(@"%@",error);
}];
}
}
在 App 程式中呼叫上面的函式,就可實現AppIcon的變更。注意,當你呼叫時,系統會彈出一個提示,讓你確定進行AppIcon 的變更操作,確定後AppIcon 才會替換。如下所示:
5、清除變更 AppIcon 時系統彈出框
我們知道系統的彈出框是由 UIAlertController 來實現的,它屬於一個控制器。在彈出的時候會呼叫 presentViewController:animated:completion: 函式。那我們可以通過這個方法來阻止彈框的彈出。由於蘋果系統的不開放性,我們也沒發更改這個函式。目前,方法就是利用執行時,用我們建立的一個方法來替換這個方法。在我們的方法中來阻止彈框的彈出。
1、核心程式碼
該段程式碼可放在繼承的控制器中或者在控制器中直接寫。匯入執行時的函式庫 #import < objc/runtime.h >。
#pragma mark 彈窗的清楚
+(void)load {
Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
Method presentAlternativeM = class_getInstanceMethod(self.class, @selector(clearPresentViewController:animated:completion:));
// 方法的切換
method_exchangeImplementations(presentM, presentAlternativeM);
}
#pragma mark 清楚處理方法
-(void)clearPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
// 跳轉頁面的型別
if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
UIAlertController * alertVctl = (UIAlertController *) viewControllerToPresent ;
if (alertVctl.title == nil && alertVctl.message == nil) {
return ;
}
}
// 頁面回撥
[self clearPresentViewController:viewControllerToPresent animated:flag completion:completion];
}
6、程式碼下載
- 程式碼下載,可在部落格下留言和郵箱。
- 可新增QQ:群號:185341804 (成功QQ吧),聯絡群主獲取。