1.准备好icon
动态修改的icon需要放在工程文件夹中,不能放在 Assets.xcassets里,但是正常的主icon还是可以放在Assets.xcassets的,若有多个尺寸一并放入即可。
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,也要在这里分别配置
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