1.準備好icon
動態修改的icon需要放在工程文件夾中,不能放在 Assets.xcassets里,但是正常的主icon還是可以放在Assets.xcassets的,若有多個尺寸一并放入即可。
image.png
2.配置info.plist
- 在info.plist中添加Icon files(iOS 5)
- 在 Icon files(iOS 5)內添加一個Key: CFBundleAlternateIcons ,類型為字典,
- 在CFBundleAlternateIcons里配置我們所有需要動態修改的icon:鍵為icon的名稱,值為一個字典(這個字典里包含兩個鍵:CFBundleIconFiles,其值類型為Array,內容為icon的名稱;UIPrerenderedIcon,其值類型為bool,內容為NO,也可以不加此key)
info.plist:如果是添加了多個尺寸icon,也要在這里分別配置
image.png
image.png
3.代碼設置
- (void)changeAppIconWithName:(NSString *)iconName {
if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
return;
}
if ([iconName isEqualToString:@""]) {
iconName = nil;
}
[[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"更換app圖標發生錯誤了 : %@",error);
}
}];
}
調用:
[self changeAppIconWithName:@"normal"];
4.去除更換時的彈窗
#import <UIKit/UIKit.h>
@interface UIViewController (ChangeAppIcon)
@end
#import "UIViewController+ChangeAppIcon.h"
#import <objc/runtime.h>
@implementation UIViewController (ChangeAppIcon)
+ (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(lq_presentViewController:animated:completion:));
method_exchangeImplementations(presentM, presentSwizzlingM);
});
}
- (void)lq_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
// NSLog(@"title : %@",((UIAlertController *)viewControllerToPresent).title);
// NSLog(@"message : %@",((UIAlertController *)viewControllerToPresent).message);
UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
if (alertController.title == nil && alertController.message == nil) {
return;
}
}
[self lq_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
@end
5.審核踩坑
上架后,蘋果拒絕認為是無效的二進制文件,郵件反饋如下
ITMS-90138: Your Info.plist contains the UINewsstandIcon sub-property under CFBundleIcons, which is intended for use with Newstand features. To include Newsstand features, the Info.plist must include the UINewsstandApp=true Info.plist key.
在info.plist中刪除Newstand