背景
项目开发过程中,可能会有更换项目图标的需求,比如一些电商的应用,在双11,618,新年等节日的时候需要显示特定的图标,但如果单单为了修改图标就要更新新版本的话,感觉有点得不偿失。这里介绍一种不需要通过更新版本就可以动态修改APP图标的方法。
注意:该方法在iOS10.3及以上有效
实现
- 导入待替换的新图片,不要放在Assets中,放到项目工程中;
- 配置 Info.plist 文件:
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>icon1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon1</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>icon2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon2</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>icon3</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon3</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon60x60</string>
</array>
</dict>
</dict>
- 通过代码替换
- (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);
}
}];
}
-
去掉更换图标时的弹框
更换图标时会出现如下弹框,可以使用Runtime来隐藏弹框
具体代码:
#import "UIViewController+Category.h"
#import <objc/runtime.h>
@implementation UIViewController (Category)
+ (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(dismissAlertViewController:animated:completion:));
//runtime方法交换,通过拦截弹框事件,实现方法转换,从而去掉弹框
method_exchangeImplementations(presentM, presentSwizzlingM);
});
}
- (void)dismissAlertViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)animated completion:(void (^)(void))completion {
if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
if (alertController.title == nil && alertController.message == nil) {
return;
}
}
[self dismissAlertViewController:viewControllerToPresent animated:animated completion:completion];
}
@end
说明
- 替换的方法不要直接放在didFinishLaunchingWithOptions 或者viewDidLoad里面,如果要放的话,给替换的图标的方法加个延时。
- 替换的图标并不需要上传多张,上传一张就可以了,不过不要太小,