动态修改app 图标(icon)

栏目: IOS · 发布时间: 6年前

内容简介:动态修改app的图标,就是在不重新安装app的情况下,可以修改当前的icon图标;在某些情况下,是有这个需求的;例如,可以更换主题的app中,一般都会有一套完整的主题包含相应的icon;还有就是一些节日主题的icon或者促销的icon,例如淘宝、京东等的节日icon。在iOS 10.3之后,苹果官方提供了相关的API来实现这个功能,主要是下面这几个方法:方法很简单,但是使用之前需要进行一些配置:

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

在iOS 10.3之后,苹果官方提供了相关的API来实现这个功能,主要是下面这几个方法:

@interface UIApplication (UIAlternateApplicationIcons)
// 如果为NO,表示当前进程不支持替换图标
@property (readonly, nonatomic) BOOL supportsAlternateIcons NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2));

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

// 如果alternateIconName为nil,则代表当前使用的是主图标.
@property (nullable, readonly, nonatomic) NSString *alternateIconName NS_EXTENSION_UNAVAILABLE("Extensions may not have alternate icons") API_AVAILABLE(ios(10.3), tvos(10.2));
@end

方法很简单,但是使用之前需要进行一些配置:

1. 配置icon

添加图片icon

动态修改的icon不能放在 Assets.xcassets 里,但是正常的主icon还是可以在这里设置的,也可以按下面的方法来设置;

首先,把需要修改的icon放在一个文件夹内:

动态修改app 图标(icon)

其文件夹内是这样的

动态修改app 图标(icon)

这里每种icon我只放了一个,如果有多个尺寸的icon,也可以直接全放进去:

动态修改app 图标(icon)

然后,文件夹会变成这样:

动态修改app 图标(icon)

这里的icon名称只需要和下面配置一致即可

配置info.plist

在info.plist中右键 -> Add Row :

输入Icon... 会有提示,选择Icon files(iOS 5)

动态修改app 图标(icon)

这时候,内容是这样的:

动态修改app 图标(icon)

这里的Icon files(iOS 5)是个字典,其中可包含的Key值有CFBundlePrimaryIcon -> Primary Icon

CFBundleAlternateIcons

UINewsstandIcon -> Newsstand Icon

这里的Primary Icon是设置app的主icon,可以在这里的Icon files数组内添加,有多个的话,依次添加,也可以这里不用填写,直接在Assets.xcassets 里配置;

下面的Newsstand Icon,暂时用不到,不用管,也可以删除。

在 Icon files(iOS 5)内添加一个Key: CFBundleAlternateIcons ,类型为字典,在这个字典里配置我们所有需要动态修改的icon:键为icon的名称,值为一个字典(这个字典里包含两个键:CFBundleIconFiles,其值类型为Array,内容为icon的名称;UIPrerenderedIcon,其值类型为bool,内容为NO,也可以不加此key),例如:

动态修改app 图标(icon)

把第一步中添加的图片全部添加进来就是这样的:

动态修改app 图标(icon)

到此,info.plist的配置即完成了;

或者将info.plist文件以 Source code 方式打开,添加以下代码:

<key>CFBundleIconskey>
    <dict>
        <key>CFBundleAlternateIconskey>
        <dict>
            <key>rainkey>
            <dict>
                <key>CFBundleIconFileskey>
                <array>
                    <string>rainstring>
                array>
                <key>UIPrerenderedIconkey>
                <false/>
            dict>
            <key>snowkey>
            <dict>
                <key>CFBundleIconFileskey>
                <array>
                    <string>snowstring>
                array>
                <key>UIPrerenderedIconkey>
                <false/>
            dict>
            <key>sunshinekey>
            <dict>
                <key>CFBundleIconFileskey>
                <array>
                    <string>sunshinestring>
                array>
                <key>UIPrerenderedIconkey>
                <false/>
            dict>
            <key>cloudykey>
            <dict>
                <key>CFBundleIconFileskey>
                <array>
                    <string>cloudystring>
                array>
                <key>UIPrerenderedIconkey>
                <false/>
            dict>
        dict>
        <key>CFBundlePrimaryIconkey>
        <dict>
            <key>CFBundleIconFileskey>
            <array>
                <string>string>
            array>
            <key>UIPrerenderedIconkey>
            <false/>
        dict>
        <key>UINewsstandIconkey>
        <dict>
            <key>CFBundleIconFileskey>
            <array>
                <string>string>
            array>
            <key>UINewsstandBindingTypekey>
            <string>UINewsstandBindingTypeMagazinestring>
            <key>UINewsstandBindingEdgekey>
            <string>UINewsstandBindingEdgeLeftstring>
        dict>
    dict>

如果是添加了多个尺寸icon,也要在这里分别配置,以上面添加的sunshine图标为例:

动态修改app 图标(icon)

使用的时候还是使用sunshine进行赋值即可!

代码

配置完成后,代码部分就比较简单了:

- (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);
        }
    }];
}

在需要修改icon的地方调用这个方法,并把相应的icon名称传进去即可:

- (IBAction)snow:(id)sender {
    [self changeAppIconWithName:@"snow"];
}
- (IBAction)rain:(id)sender {
    [self changeAppIconWithName:@"rain"];
}
- (IBAction)cloudy:(id)sender {
    [self changeAppIconWithName:@"rain"];
}
- (IBAction)sunshine:(id)sender {
    [self changeAppIconWithName:@"sunshine"];
}

示意图:

动态修改app 图标(icon)

设置iPad动态图标

iPad的动态图标设置和上面步骤基本一样,有的文章说是将 CFBundleIcons 改为 CFBundleIcons~ipad,即:

动态修改app 图标(icon)

但是,在测试中发现,使用上面的key值也是可以实现动态改变的,即不做任何修改,iPhone和iPad使用相同的配置,即:CFBundleIcons。

去掉更换icon时的弹框

从上面的示意图可以发现,在设置icon的时候,会有个系统弹框,这样有时候会不太友好,我们可以使用Runtime,对UIViewController进行扩展来隐藏这个弹框:

// UIViewController+LQNoPresent.h
#import

@interface UIViewController (LQNoPresent)

@end


// UIViewController+LQNoPresent.m

#import "UIViewController+LQNoPresent.h"
#import

@implementation UIViewController (LQNoPresent)

+ (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

这样在切换图标的时候就没有系统的弹框了:

动态修改app 图标(icon)

参考文章

iOS 10.3 如何更换 app 图标

作者:流火绯瞳

链接:https://www.jianshu.com/p/69313970d0e7


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Build Your Own Web Site the Right Way Using HTML & CSS

Build Your Own Web Site the Right Way Using HTML & CSS

Ian Lloyd / SitePoint / 2006-05-02 / USD 29.95

Build Your Own Website The Right Way Using HTML & CSS teaches web development from scratch, without assuming any previous knowledge of HTML, CSS or web development techniques. This book introduces you......一起来看看 《Build Your Own Web Site the Right Way Using HTML & CSS》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具