美文网首页
程序内动态修改appIcon+Method Swizzling

程序内动态修改appIcon+Method Swizzling

作者: 西门淋雨 | 来源:发表于2018-09-03 11:17 被阅读6次

    程序内动态修改appIcon

    #import <UIKit/UIKit.h>
    
    @interface ChangeAppIconVC : UIViewController
    
    @end
    
    
    #import "ChangeAppIconVC.h"
    
    @interface ChangeAppIconVC ()
    
    @end
    
    @implementation ChangeAppIconVC
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
    
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.backgroundColor = [UIColor lightGrayColor];
        [btn setTitle:@"换新的icon" forState:UIControlStateNormal];
        [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(changeIocn:) forControlEvents:UIControlEventTouchUpInside];
        btn.frame = CGRectMake((CGRectGetWidth(self.view.frame)-200)*0.5, 100, 200, 30);
        btn.tag = 100;
        btn.titleLabel.font = [UIFont systemFontOfSize:15];
        [self.view addSubview:btn];
        
        UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
        btn2.backgroundColor = [UIColor lightGrayColor];
        [btn2 setTitle:@"换原来的icon" forState:UIControlStateNormal];
        [btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [btn2 addTarget:self action:@selector(changeIocn:) forControlEvents:UIControlEventTouchUpInside];
        btn2.frame = CGRectMake((CGRectGetWidth(self.view.frame)-200)*0.5, 200, 200, 30);
        btn2.tag = 200;
        btn2.titleLabel.font = [UIFont systemFontOfSize:15];
        [self.view addSubview:btn2];
    
    }
    - (void)changeIocn:(UIButton *)sender{
        if (sender.tag == 100) {
            [self changeAppIconWithName:@"DYICON"];
        }else{
            [self changeAppIconWithName:@""];
        }
    }
    - (void)changeAppIconWithName:(NSString *)iconName {
        if (@available(iOS 10.3, *)) {
            if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
                return;
            }
            if ([iconName isEqualToString:@""]) {
                iconName = nil;
            }
            [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
                if (error) {
                    NSLog(@"更换app图标发生错误了 : %@",error);
                }
            }];
        } else {
            UIAlertController *myAlertCon = [UIAlertController alertControllerWithTitle:@"提示" message:@"支持10.3以及以上版本" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                
            }];
            [myAlertCon addAction:okAction];
            [self presentViewController:myAlertCon animated:YES completion:nil];
        }
    
    }
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    
    @end
    

    然后需要配置相关的图片:

    1.默认的图片:
    默认icon
    2.新增图片:
    新增icon
    3.plist文件的配置,主要的是3,1和2 是默认就有的,不需要做修改。“DYICON”即要替换的新的icon 的图片集合。
    plist配置

    上述代码就可以程序内替换图片了,相关的方法要求10.3以及以上。但是每次替换icon后都会弹框提示,不是很友好,可以用runtime去掉弹框。

    #import <UIKit/UIKit.h>
    
    @interface UIViewController (HideAlert)
    
    @end
    
    #import "UIViewController+HideAlert.h"
    #import <objc/runtime.h>
    @implementation UIViewController (HideAlert)
    
    + (void)load{
        Method originalMethod = class_getInstanceMethod([self class], @selector(presentViewController:animated:completion:));
        Method swizzlingMethod = class_getInstanceMethod([self class], @selector(swizzlingPresentViewController:animated:completion:));
        BOOL didAddMethod = class_addMethod([self class], @selector(presentViewController:animated:completion:), method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));
        
        if (didAddMethod) {
            class_replaceMethod([self class], @selector(swizzlingPresentViewController:animated:completion:), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        }else{
            method_exchangeImplementations(originalMethod, swizzlingMethod);
        }
    }
    - (void)swizzlingPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
        if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
            UIAlertController *alertCon = (UIAlertController *)viewControllerToPresent;
            if (alertCon.title == nil && alertCon.message == nil) {
                UIAlertController *myAlertCon = [UIAlertController alertControllerWithTitle:@"提示" message:@"图标已替换" preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                    
                }];
                [myAlertCon addAction:okAction];
                //这里会重新走swizzlingPresentViewController方法,然后alertCon.title != nil && alertCon.message != nil,然后执行swizzlingPresentViewController方法,其实是走的系统的presentViewController方法,方法结束。
    //            [self presentViewController:myAlertCon animated:YES completion:nil];
                
                //如果调用这个方法则直接走的是系统的presentViewController的方法,然后方法结束
                [self swizzlingPresentViewController:myAlertCon animated:YES completion:nil];
                return;
            }
        }
        [self swizzlingPresentViewController:viewControllerToPresent animated:flag completion:completion];
    }
    @end
    

    git Demo地址

    相关文章

      网友评论

          本文标题:程序内动态修改appIcon+Method Swizzling

          本文链接:https://www.haomeiwen.com/subject/bidbwftx.html