动态修改app图标(icon)
动态修改app的图标,就是在不重新安装app的情况下,可以修改当前的icon图标;在某些情况下,是有这个需求的;例如,可以更换 主题的app中,一般都会有一套完整的主题包含相应的icon;还有就是一些节日主题的icon或者促销的icon,例如淘宝、京东等的节日icon。

@interface UIApplication (UIAlternateApplicationIcons)
// 如果为NO,表示当前进程不支持替换图标
@property (readonly, nonatomic) BOOL supportsAlternateIcons;

// 传入nil代表使用主图标. 完成后的操作将会在任意的后台队列中异步执行; 如果需要更改UI,请确保在主队列中执行.
- (void)setAlternateIconName:(nullable NSString *)alternateIconName completionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;

// 如果alternateIconName为nil,则代表当前使用的是主图标.
@property (nullable, readonly, nonatomic) NSString *alternateIconName;
@end

一、配置icon
动态修改的icon不能放在 Assets.xcassets 里,直接以文件的放在文件中;

二、配置info.plist 文件

屏幕快照 2020-01-06 下午8.02.10.png

这里的Icon files(iOS 5)是个字典,其中可包含的Key值有CFBundlePrimaryIcon -> 
这里的Primary Icon是设置app的主icon,可以在这里的Icon files数组内添加,有多个的话,依次添加,也可以这里不用填写,直接在Assets.xcassets 里配置; 
下面的Newsstand Icon,暂时用不到,不用管,也可以删除。

三、执行代码

- (void)clickButton {
    if (@available(iOS 10.3, *)) {
        if (UIApplication.sharedApplication.supportsAlternateIcons) {
            [[UIApplication sharedApplication] setAlternateIconName:@"sub" completionHandler:^(NSError * _Nullable error) {
                NSLog(@"error =%@", error);
            }];
        }
    } else {
        NSLog(@"系统不支持");
    }
}

四、解决烦人的弹框问题

先引入: #import <objc/runtime.h>

+ (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]]) {
        UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
        if (alertController.title == nil && alertController.message == nil) {
            return;
        }
    }
    [self lq_presentViewController:viewControllerToPresent animated:flag completion:completion];
}