iOS-动态替换appicon

参考:动态更换appIcon

  • 该方法只能在系统版本iOS10.3及以上版本才可以使用。

  • 需要先内置要更换的主题icon

  • 动态更换的icon不能放在 Assets.xcassets里,主icon可以,默认的主icon可以放在Assets.xcassets

  • 在首页的viewDidLoad里调用setAlternateIconName,报了NSUserCancelledError:3072。放在viewDidAppear里调用可正常使用。


    1. info.plist中,添加Icon files(iOS 5):
      Primary Icon(主icon):设置app的主icon,可以在这里的Icon files数组内添加,有多个的话,依次添加,也可以这里不用填写,直接在Assets.xcassets 里配置;
      Newsstand Icon(期刊icon):设置所有用户订阅的报刊和杂志类的图标,目前我们用不到,先不用管。
      CFBundleAlternateIcons(新增动态icon配置Array): 新增一栏,需要新增的icon配置在这。

      CFBundleIconFiles:其值类型为Array,内容为icon的名称
      UIPrerenderedIcon:其值类型为bool,内容为NO,也可以不加此key

    1. 新增文件夹,放置需要动态切换的icon文件。
    1. 在配置的CFBundleIconFiles里添加动态切换对应主题的图片。
    1. 代码实现icon切换
    • a) 实现icon切换逻辑
    - (void)glHandleChangeAppIconWith:(NSString *)iconType {
        if (@available(iOS 10.3, *)) {
            if (![UIApplication sharedApplication].supportsAlternateIcons) {
                return;
            }
            NSString *iconNameStr = nil;
            NSString *alternateIconName = [[UIApplication sharedApplication] alternateIconName];
                //重置到默认icon
            if ([iconType isEqual:@"1"]) { // 切换主题
                iconNameStr = @"icon_newYears";
            }else { // 默认主icon
                iconNameStr = nil;
            }
            if ((!alternateIconName) && (!iconNameStr)) { // 都是nil不处理,已是默认icon了
    
            }else {
                if ([alternateIconName isEqual:iconNameStr]) { // 总有个非nil 且相等 已是设置过的了,不处理,
    
                }else {// 总有个非nil 且不相等 更换
                    [self glSetAppIconWithName:iconNameStr];
                }
            }
        }
    }
    
    - (void)glSetAppIconWithName:(NSString *)iconNameStr {
        if (@available(iOS 10.3, *)) {
            if ([[UIApplication sharedApplication] respondsToSelector:@selector(supportsAlternateIcons)] &&
                [[UIApplication sharedApplication] supportsAlternateIcons]) {
                [[UIApplication sharedApplication] setAlternateIconName:iconNameStr completionHandler:^(NSError * _Nullable error) {
                    DEBUGLog(@"替换icon:iconNameStr:%@ ===:%@", iconNameStr, error);
                }];
            }
        }
    }
    
    • b) 隐藏已切换icon的提示:
    // 找了好几种办法,还是得在类里头写才能隐藏弹框,搞不懂运行时,UIViewController (HidenChangeAlert)先这么用着吧 ..
    + (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(gl_presentViewController:animated:completion:));
            method_exchangeImplementations(presentM, presentSwizzlingM);
        });
    }
    
    - (void)gl_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
        if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
    //        DEBUGLog(@"title runtime : %@",((UIAlertController *)viewControllerToPresent).title);
    //        DEBUGLog(@"message runtime : %@",((UIAlertController *)viewControllerToPresent).message);
            UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
            if (alertController.title == nil && alertController.message == nil) {
                return;
            } else {
                [self gl_presentViewController:viewControllerToPresent animated:flag completion:completion];
                return;
            }
        }
        [self gl_presentViewController:viewControllerToPresent animated:flag completion:completion];
    }
    
    

截屏2021-12-21 09.24.41.png
截屏2021-12-21 14.20.02.png
截屏2021-12-22 15.05.55.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容