iOS 动态更换 APP图标

2021-11-24  本文已影响0人  yuebiubiu

背景

项目开发过程中,可能会有更换项目图标的需求,比如一些电商的应用,在双11,618,新年等节日的时候需要显示特定的图标,但如果单单为了修改图标就要更新新版本的话,感觉有点得不偿失。这里介绍一种不需要通过更新版本就可以动态修改APP图标的方法。

注意:该方法在iOS10.3及以上有效

实现

  1. 导入待替换的新图片,不要放在Assets中,放到项目工程中;
  2. 配置 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>

  1. 通过代码替换
- (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);
        }
    }];
}
  1. 去掉更换图标时的弹框
    更换图标时会出现如下弹框,可以使用Runtime来隐藏弹框


    弹框.jpg

具体代码:

#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

说明

  1. 替换的方法不要直接放在didFinishLaunchingWithOptions 或者viewDidLoad里面,如果要放的话,给替换的图标的方法加个延时。
  2. 替换的图标并不需要上传多张,上传一张就可以了,不过不要太小,
上一篇 下一篇

猜你喜欢

热点阅读