<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont

简介: 1、iOS 10.3 开放了更换 app 图标的 API,核心方法是下面这个:[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^( }];这是官方文档,但是你还需要在 info.plist 里面填一些东西才能让它起作用,这部分官方注释内容在这里。


1、iOS 10.3 开放了更换 app 图标的 API,核心方法是下面这个:

[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(

 }];

这是官方文档,但是你还需要在 info.plist 里面填一些东西才能让它起作用,这部分官方注释内容在这里



2、 info.plist 如何填写呢?一时可能搞不清楚如何操作,下面做个实例:







3、具体如下:



<key>CFBundleIcons</key>
    <dict>
        <key>CFBundleAlternateIcons</key>
        <dict>
            <key>newIcon</key>
            <dict>
                <key>CFBundleIconFiles</key>
                <array>
                    <string>newIcon</string>
                </array>
                <key>UIPrerenderedIcon</key>
                <false/>
            </dict>
        </dict>
        <key>CFBundlePrimaryIcon</key>
        <dict>
            <key>CFBundleIconFiles</key>
            <array>
                <string>Icon60X60</string>
            </array>
        </dict>
    </dict>

如图,Primary Icon 字段写为 Icon60X60 是因为这里 xcassets 里面我只导入了 60pt@2x 和 60pt@3x 的图片资源,这里选为 60 是因为对于 iPhone,60pt 的图片资源图标所需最高质量,更低分辨率的版本系统会自动压缩以展示。

newIcon 是我的用于替换原生图标的图片资源。文件名需要和 info.plist 中保持一致(注意 info.plist 中用到了两次 "newIcon"),同时这也是你在代码中设置图标时,需要给 API 传入的参数。同样是 60pt@2x 和 60pt@3x 的图片资源,文件不通过 Assets.xcassets 添加进来,而是直接放到目录中。

如果你需要支持 iPad,建议这里使用 83.5pt(iPad Pro)的图片资源。另外还有些其他关于在 iPad 上替换图标的注意事项,在这里有说明,注意我们这里在 info.plist 里面所用的 key 是 CFBundleIcons,还有另外一个 key 是 CFBundleIcons~ipad

4、替换图标部分的代码:

- (void)changeAppIcon
{
    if ([UIApplication sharedApplication].supportsAlternateIcons) {
        NSLog(@"you can change this app's icon");
    }else{
        NSLog(@"you can not change this app's icon");
        return;
    }
    
    NSString *iconName = [[UIApplication sharedApplication] alternateIconName];
    
    if (iconName) {
        // change to primary icon
        [[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"set icon error: %@",error);
            }
            NSLog(@"The alternate icon's name is %@",iconName);
        }];
    }else{
        // change to alterante icon
        [[UIApplication sharedApplication] setAlternateIconName:@"newIcon" completionHandler:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"set icon error: %@",error);
            }
            NSLog(@"The alternate icon's name is %@",iconName);
        }];
    }
}

5、最终效果如下:



优化:

很多人就说了,每次都要弹框修改多费劲啊,能不能优化在后台切换icon呢?我的答案是:能!

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self runtimeReplaceAlert];
}

// 利用runtime来替换展现弹出框的方法
- (void)runtimeReplaceAlert
{
    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(ox_presentViewController:animated:completion:));
        // 交换方法实现
        method_exchangeImplementations(presentM, presentSwizzlingM);
    });
}

// 自己的替换展示弹出框的方法
- (void)ox_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);
        
        // 换图标时的提示框的title和message都是nil,由此可特殊处理
        UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
        if (alertController.title == nil && alertController.message == nil) { // 是换图标的提示
            return;
        } else {// 其他提示还是正常处理
            [self ox_presentViewController:viewControllerToPresent animated:flag completion:completion];
            return;
        }
    }
    
    [self ox_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
优化后的效果如下:




手机加iOS开发者交流QQ群: 446310206

Demo:GitHub  喜欢记得star一下哦!



目录
相关文章
|
Web App开发 前端开发
|
Web App开发 存储 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
1.HBase依赖于HDFS,HBase按照列族将数据存储在不同的hdfs文件中;MongoDB直接存储在本地磁盘中,MongoDB不分列,整个文档都存储在一个(或者说一组)文件中 (存储) 2.
696 0
|
存储 监控 数据库
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
为首次部署MongoDB做好准备:容量计划和监控 作者Mat Keep ,译者孙镜涛如果你已经完成了自己新的MongoDB应用程序的开发,并且现在正准备将它部署进产品中,那么你和你的运营团队需要讨论一些关键的问题: 最佳部署实践是什么? 为了确保应用程序满足它所必须的服务层次我们需要监控哪些关键指标? 如何能够确定添加分片的时机? 有哪些工具可以对数据库进行备份和恢复? 怎样才能安全地访问所有新的实时大数据? 本文介绍了硬件选择、扩展、HA和监控。
2556 0
|
Web App开发 Apache
|
Web App开发 前端开发 Java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
服务端需在vm arguments一栏下加上    -agentlib:jdwp=transport=dt_socket,server=y,address=8000 并以run模式启动 如果以debug模式启动服务端...
697 0
|
Web App开发 前端开发 Java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
 Connection reset by peer的常见原因: 1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接关闭;    如果知道实际连接服务器的并发客户数没有超过服务器的承载量,看下有没有网络流量异常。
829 0
|
Web App开发 前端开发 Java
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
kafka.common.ConsumerRebalanceFailedException: group_dd-1446432618163-2746a209 can't rebalance after 10 retries  at kafka.
786 0
|
Web App开发 前端开发 Java
|
Web App开发 前端开发 测试技术
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
ClusterId read in ZooKeeper is null. Re-running the program after fixing issue 1 will result in the following e...
784 0