該方法只能在系統(tǒng)版本iOS10.3及以上版本才可以使用。
需要先內置要更換的主題icon
動態(tài)更換的icon不能放在
Assets.xcassets里,主icon可以,默認的主icon可以放在Assets.xcassets里在首頁的
viewDidLoad里調用setAlternateIconName,報了NSUserCancelledError:3072。放在viewDidAppear里調用可正常使用。
-
在
info.plist中,添加Icon files(iOS 5):
Primary Icon(主icon):設置app的主icon,可以在這里的Icon files數組內添加,有多個的話,依次添加,也可以這里不用填寫,直接在Assets.xcassets 里配置;
Newsstand Icon(期刊icon):設置所有用戶訂閱的報刊和雜志類的圖標,目前我們用不到,先不用管。
CFBundleAlternateIcons(新增動態(tài)icon配置Array): 新增一欄,需要新增的icon配置在這。CFBundleIconFiles:其值類型為Array,內容為icon的名稱;
UIPrerenderedIcon:其值類型為bool,內容為NO,也可以不加此key
-
- 新增
文件夾,放置需要動態(tài)切換的icon文件。
- 新增
- 在配置的
CFBundleIconFiles里添加動態(tài)切換對應主題的圖片。
- 在配置的
-
- 代碼實現(xiàn)icon切換
- a) 實現(xiàn)icon切換邏輯
- (void)glHandleChangeAppIconWith:(NSString *)iconType { if (@available(iOS 10.3, *)) { if (![UIApplication sharedApplication].supportsAlternateIcons) { return; } NSString *iconNameStr = nil; NSString *alternateIconName = [[UIApplication sharedApplication] alternateIconName]; //重置到默認icon if ([iconType isEqual:@"1"]) { // 切換主題 iconNameStr = @"icon_newYears"; }else { // 默認主icon iconNameStr = nil; } if ((!alternateIconName) && (!iconNameStr)) { // 都是nil不處理,已是默認icon了 }else { if ([alternateIconName isEqual:iconNameStr]) { // 總有個非nil 且相等 已是設置過的了,不處理, }else {// 總有個非nil 且不相等 更換 [self glSetAppIconWithName:iconNameStr]; } } } } - (void)glSetAppIconWithName:(NSString *)iconNameStr { if (@available(iOS 10.3, *)) { if ([[UIApplication sharedApplication] respondsToSelector:@selector(supportsAlternateIcons)] && [[UIApplication sharedApplication] supportsAlternateIcons]) { [[UIApplication sharedApplication] setAlternateIconName:iconNameStr completionHandler:^(NSError * _Nullable error) { DEBUGLog(@"替換icon:iconNameStr:%@ ===:%@", iconNameStr, error); }]; } } }- b) 隱藏已切換icon的提示:
// 找了好幾種辦法,還是得在類里頭寫才能隱藏彈框,搞不懂運行時,UIViewController (HidenChangeAlert)先這么用著吧 .. + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:)); Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(gl_presentViewController:animated:completion:)); method_exchangeImplementations(presentM, presentSwizzlingM); }); } - (void)gl_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) { // DEBUGLog(@"title runtime : %@",((UIAlertController *)viewControllerToPresent).title); // DEBUGLog(@"message runtime : %@",((UIAlertController *)viewControllerToPresent).message); UIAlertController *alertController = (UIAlertController *)viewControllerToPresent; if (alertController.title == nil && alertController.message == nil) { return; } else { [self gl_presentViewController:viewControllerToPresent animated:flag completion:completion]; return; } } [self gl_presentViewController:viewControllerToPresent animated:flag completion:completion]; }

截屏2021-12-21 09.24.41.png

截屏2021-12-21 14.20.02.png

截屏2021-12-22 15.05.55.png