思路
- iOS 10.3 以后开放了更换图标的接口,调用方法切换
- 在mainbundle中放置要切换的图标文件
- 在info.plist文件中配置相关参数告知系统要切换的图标的详细信息
解决步骤
-
bundle添加图片
image.png -
配置info.plist文件,增加参数
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>晴</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>晴20x20</string>
<string>晴29x29</string>
<string>晴40x40</string>
<string>晴60x60</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>jh</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>jh20*20</string>
<string>jh29*29</string>
<string>jh40*40</string>
<string>jh60*60</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>super</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>super20*20</string>
<string>super29*29</string>
<string>super40*40</string>
<string>super60*60</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
</dict>
最终效果
image.png
左边的红圈名称是代码里需要传入的图片名称,右侧的红圈是系统根据不同的场景选择对应的图标
- 最后关键性代码
[[UIApplication sharedApplication] setAlternateIconName:@"newicon" completionHandler:^(NSError * _Nullable error) {
if (error) {
//do something
}
}];
- 补充:判断系统是否可以更换图标 返回是一个布尔值
[UIApplication sharedApplication].supportsAlternateIcons
判断app是否更换过图标
[[UIApplication sharedApplication] alternateIconName]
返回为null表示系统用的是默认icon,返回那么则表示正在使用更换后的图标
完。
=========================06-28补充==========
更换图标成功后,系统会默认弹出对话框,如果想不显示对话框,思路是在执行方法的控制器里拦截弹出对话框,方法是用runtime交换到自己的方法,在自己的方法里盘进行过滤,如果是切换图标的提示,不做任何操作,剩余情况全部按照原方法执行。过滤的条件是切换图标提示的alert,标题和提示内容均为空,以下是实现代码
//在viewdidload方法里执行此方法,进行交换
- (void)exchangeMethod{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method originalMethod = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
Method newMethod = class_getInstanceMethod(self.class, @selector(jh_presentViewController:animated:completion:));
// 交换方法实现
method_exchangeImplementations(originalMethod, newMethod);
});
}
// 最终的目的是 不显示alert弹窗
- (void)jh_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
//换图标的提示为空
UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
if (alertController.title == nil && alertController.message == nil) { // 两者皆为空 不做任何处理
return;
} else {//已经经过交换,走系统正常的方法
[self jh_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}else{//已经经过交换,走系统正常的方法
[self jh_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}
网友评论