iOS新特性: iOS10.3教你如何动态更换APP图标

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

[objc]  view plain  copy
  1. [[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(  
  2.   
  3.  }];  

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



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







3、具体如下:



[objc]  view plain  copy
  1. <key>CFBundleIcons</key>  
  2.     <dict>  
  3.         <key>CFBundleAlternateIcons</key>  
  4.         <dict>  
  5.             <key>newIcon</key>  
  6.             <dict>  
  7.                 <key>CFBundleIconFiles</key>  
  8.                 <array>  
  9.                     <string>newIcon</string>  
  10.                 </array>  
  11.                 <key>UIPrerenderedIcon</key>  
  12.                 <false/>  
  13.             </dict>  
  14.         </dict>  
  15.         <key>CFBundlePrimaryIcon</key>  
  16.         <dict>  
  17.             <key>CFBundleIconFiles</key>  
  18.             <array>  
  19.                 <string>Icon60X60</string>  
  20.             </array>  
  21.         </dict>  
  22.     </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、替换图标部分的代码:

[objc]  view plain  copy
  1. - (void)changeAppIcon  
  2. {  
  3.     if ([UIApplication sharedApplication].supportsAlternateIcons) {  
  4.         NSLog(@"you can change this app's icon");  
  5.     }else{  
  6.         NSLog(@"you can not change this app's icon");  
  7.         return;  
  8.     }  
  9.       
  10.     NSString *iconName = [[UIApplication sharedApplication] alternateIconName];  
  11.       
  12.     if (iconName) {  
  13.         // change to primary icon  
  14.         [[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {  
  15.             if (error) {  
  16.                 NSLog(@"set icon error: %@",error);  
  17.             }  
  18.             NSLog(@"The alternate icon's name is %@",iconName);  
  19.         }];  
  20.     }else{  
  21.         // change to alterante icon  
  22.         [[UIApplication sharedApplication] setAlternateIconName:@"newIcon" completionHandler:^(NSError * _Nullable error) {  
  23.             if (error) {  
  24.                 NSLog(@"set icon error: %@",error);  
  25.             }  
  26.             NSLog(@"The alternate icon's name is %@",iconName);  
  27.         }];  
  28.     }  
  29. }  

5、最终效果如下:



优化:

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

[objc]  view plain  copy
  1. - (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.     // Do any additional setup after loading the view, typically from a nib.  
  4.     [self runtimeReplaceAlert];  
  5. }  
  6.   
  7. // 利用runtime来替换展现弹出框的方法  
  8. - (void)runtimeReplaceAlert  
  9. {  
  10.     static dispatch_once_t onceToken;  
  11.     dispatch_once(&onceToken, ^{  
  12.         Method presentM = class_getInstanceMethod(self.class@selector(presentViewController:animated:completion:));  
  13.         Method presentSwizzlingM = class_getInstanceMethod(self.class@selector(ox_presentViewController:animated:completion:));  
  14.         // 交换方法实现  
  15.         method_exchangeImplementations(presentM, presentSwizzlingM);  
  16.     });  
  17. }  
  18.   
  19. // 自己的替换展示弹出框的方法  
  20. - (void)ox_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {  
  21.       
  22.     if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {  
  23.         NSLog(@"title : %@",((UIAlertController *)viewControllerToPresent).title);  
  24.         NSLog(@"message : %@",((UIAlertController *)viewControllerToPresent).message);  
  25.           
  26.         // 换图标时的提示框的title和message都是nil,由此可特殊处理  
  27.         UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;  
  28.         if (alertController.title == nil && alertController.message == nil) { // 是换图标的提示  
  29.             return;  
  30.         } else {// 其他提示还是正常处理  
  31.             [self ox_presentViewController:viewControllerToPresent animated:flag completion:completion];  
  32.             return;  
  33.         }  
  34.     }  
  35.       
  36.     [self ox_presentViewController:viewControllerToPresent animated:flag completion:completion];  
  37. }  
优化后的效果如下:


猜你喜欢

转载自blog.csdn.net/lu_ca/article/details/78904538
今日推荐