[iOS]动态修改app 图标(icon)

点击上方“iOS开发”,选择“置顶公众号”

关键时刻,第一时间送达!

640?640?wx_fmt=gif


作者:流火绯瞳

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

iOS开发整理发布,转载请联系作者获得授权


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


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


 
 

@interface UIApplication (UIAlternateApplicationIcons)
// 如果为NO,表示当前进程不支持替换图标
@property (readonlynonatomicBOOL 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 (nullablereadonlynonatomicNSString *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放在一个文件夹内:


640?wx_fmt=other


其文件夹内是这样的


640?wx_fmt=other


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


640?wx_fmt=other


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


640?wx_fmt=other


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


配置info.plist


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


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


640?wx_fmt=other


这时候,内容是这样的:


640?wx_fmt=other


这里的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),例如:


640?wx_fmt=other


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


640?wx_fmt=other


到此,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图标为例:


640?wx_fmt=other


使用的时候还是使用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"];
}


示意图:


640?wx_fmt=gif


设置iPad动态图标


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


640?wx_fmt=other


但是,在测试中发现,使用上面的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


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


640?wx_fmt=gif


参考文章


iOS 10.3 如何更换 app 图标

640?wx_fmt=gif640?【点击成为源码大神】

▼点击「阅读原文」进入程序员商城

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: uniapp 是一种跨平台开发框架,可以实现一次编写同时发布到多个平台,包括iOS和安卓。在uniapp中,动态修改app应用图标是可以实现的。 首先,要实现动态修改app应用图标,我们需要使用uniapp提供的原生插件功能。原生插件是提供给uniapp开发者与原生代码进行交互的一种机制。可以通过编写原生插件来实现一些uniapp本身不支持的功能。 其次,我们需要在原生代码中实现修改应用图标的功能。具体的实现方法会因为平台不同而有所差异。对于iOS平台,我们可以通过修改应用的Info.plist文件中的CFBundleIconName属性来更换应用图标。这个属性对应的是应用包内存放应用图标文件的名称。我们可以通过在原生代码中动态修改这个文件名来实现动态更换图标的效果。对于安卓平台,我们可以通过修改应用的AndroidManifest.xml文件中的android:icon属性来更换应用图标。与iOS类似,我们也可以通过在原生代码中动态修改这个属性的值来实现动态更换图标的效果。 最后,我们需要在uniapp中调用原生插件提供的接口来实现动态更换应用图标的功能。可以通过在uniapp的逻辑代码中监听用户的操作,当用户触发更换图标的操作时,调用原生插件提供的接口来实现应用图标的更换。可以根据不同的操作系统平台来调用不同的原生插件接口。 总之,通过使用uniapp的原生插件机制和对应平台的原生代码,我们可以实现在uniapp动态修改app应用图标的功能。这样用户可以根据自己的喜好或者不同的场景,来随时更换应用图标,增加应用的个性化和多样性。 ### 回答2: UniApp是一款跨平台的应用开发框架,支持使用Vue.js进行开发,并能在多个平台上同时运行。动态修改UniApp应用图标是一种实现个性化展示和用户体验的方法。 UniApp支持在不同平台上自定义应用图标的功能,例如在Android平台上可以通过manifest.json文件的`icons`字段来配置应用图标,而在iOS平台上可以通过uni-config.json的`icons`字段来配置应用图标。这些配置文件可以在UniApp项目中找到。 要实现动态修改应用图标,首先需要准备好不同图标的资源文件,这些文件可以是不同尺寸和不同格式的图片。接下来,在应用中通过监听用户的操作或者其他触发条件,获取需要切换的图标信息。 在获取到需要切换的图标信息后,可以使用UniApp提供的平台相关API来进行动态修改。例如在Android平台上可以使用uni.requestUpdateApp方法来请求更新应用图标,而在iOS平台上可以使用uni.setTabBarStyle方法来设置应用图标的样式。 在实际实现过程中,需要根据具体平台的要求和限制来进行相应的操作。同时也要注意在应用内进行图标切换时给予用户相应的提示和选择,以保证用户体验的一致性和便利性。 总结来说,UniApp支持动态修改应用图标的功能,但具体的实现方式要根据不同的平台和需求来进行相应的配置和操作。这样可以提供更好的用户体验和个性化的展示效果。 ### 回答3: UniApp是一种跨平台的应用开发框架,可以用于开发同时运行在多个平台的应用程序。动态修改UniApp应用的图标是指在应用运行时,可以通过代码动态地改变应用的图标。 UniApp框架本身并没有直接提供修改应用图标的功能,但可以通过一些技巧来实现。在UniApp中,可以通过动态切换应用启动页的方式来实现实质上的应用图标变化。 具体操作步骤如下: 1. 开发者可以准备好不同的应用图标资源文件,例如不同颜色、不同风格的图标。 2. 在UniApp的启动页中通过代码逻辑来判断需要显示的图标,并将对应的图标资源文件路径传递给页面。 3. 在启动页的页面对应位置引用图标资源,并设置为应用图标。 4. 当应用启动时,启动页会根据传递的图标资源文件路径动态加载对应图标,并将其设置为应用的图标需要注意的是,动态修改应用图标的方式在不同平台上可能会有不同的实现方法。由于UniApp是跨平台的框架,开发者需要针对不同平台分别处理图标动态切换。可以通过判断运行的平台类型,然后调用对应平台的接口来实现图标动态切换。 总结来说,UniApp框架虽然没有直接提供动态修改应用图标的功能,但借助启动页的切换机制,开发者可以通过代码实现应用图标动态变化。这种方式需要在不同平台上分别处理,为每个平台准备对应的图标资源文件,并通过代码逻辑来判断和切换图标

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值