聲明:
轉載請注明出處:http://www.lxweimin.com/p/9c78f161eeb8
評論請到原文,轉載一概不回復
iOS動態更換App圖標方法就不說了,這里給一篇詳細的介紹文章:iOS動態更換App圖標(一):基礎使用
這里只說一下遇到的坑
坑1
setAlternateIconName
不能在didFinishLaunchingWithOptions
中調用,會報3072錯誤,需要在ViewController
中調用,初步猜想可能是需要window
初始化成功后調用,需要一個ViewController
或者是UINavigationController
之類的,沒有去驗證
坑2
supportsAlternateIcons
只是檢測是否能進行更換,并不能進行系統版本號判斷,需要自己進行版本判斷,要不然在低版本系統中會崩潰,比如:iOS7
坑3
icon資源文件需要在項目目錄下,不能是Assets.xcassets
中的圖片,否則無效
技巧點1
動態更換App圖標會有彈框,這個可以去掉,教程:iOS動態更換App圖標(二):無彈框更換App圖標
其實不用非要使用擴展,寫在調用setAlternateIconName
的ViewController
里面就可以了,在調用setAlternateIconName
前使用代碼
Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(dy_presentViewController:animated:completion:));
// 交換方法實現
method_exchangeImplementations(presentM, presentSwizzlingM);
比如:
- (void)viewDidLoad {
[super viewDidLoad];
Method presentM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
Method presentSwizzlingM = class_getInstanceMethod(self.class, @selector(dy_presentViewController:animated:completion:));
// 交換方法實現
method_exchangeImplementations(presentM, presentSwizzlingM);
NSString *alternateIconName = [[UIApplication sharedApplication] alternateIconName];
if (alternateIconName) {
//重置到默認icon
[self setAppIconWithName:nil];
} else {
NSString *IconName = @"AppIcon-1";
[self setAppIconWithName:IconName];
}
}
- (void)setAppIconWithName:(NSString *)iconName {
if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
return;
}
if ([iconName isEqualToString:@""]) {
iconName = nil;
}
[[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"更換app圖標發生錯誤了:\n%@",error);
}
}];
}
- (void)dy_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;
} else {
[self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
return;
}
}
[self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
}
技巧點2
plist
的CFBundleIcons
中不需要設置默認圖片,只需要設置替換的圖片就可以了,UIPrerenderedIcon
也不需要設置,這個是iOS7之前的參數(如果你現在還在支持iOS6,我只能說上帝保佑你,可憐的孩子!),比如:
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AppIcon-1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon-1</string>
</array>
</dict>
</dict>
</dict>
使用的時候參考我上面提供的代碼就行了
我只是粗略測試了一下,如果有出錯的地方謝謝大家指出來
另外如果想在編譯的時候就把圖標替換了,可以使用腳本來做,這樣就不能在運行時替換了
--------------------6.7
附上jenkins打包替換圖標方法,沒寫過jenkins腳本的就要看了,我寫的比較粗略