Xcode 集成多套测试 App 图标

实现多套 App 图标依赖** Xcode13及以上版本**

Xcode13之前,如果要实现 iOS App 动态切换图标需要Info.plist添加**CFBundleAlternatelcons**相关字段声明对应的备用图标。如果要多套 App 图标,那么需要添加很多标签,不够直观和高效。
所以,在 Xcode 13 开始,可以通过项目Assets.xcassets创建 AppIcon 图标模板的形式,直观又方便管理图标。

如何给App添加多套图标

添加多套icon,跟平时添加应用icon一样,由于笔者没有完整的一整套icon这里有部分icon没有添加上,实际开发中,必须添加所有尺寸icon (注意,需要将每套的icon图片名称保持一致!)

在这里插入图片描述

然后工程Build SettingsInclude all app icon assets改为 YES(注意,需要 Xcode 13 以上才有这个字段!)

在这里插入图片描述

如何验证是否配置多套图标成功了

编译查看Product文件夹中的包体,或者Archive查看包体中的 Info.plist文件Icon files (iOS 5) 配置下是否有 CFBundleAlternateIcons 对应的多套图标的名字,如下图

在这里插入图片描述

如何通过代码动态替换应用图标

Objective-C 代码动态替换应用图标如下

注意:动态替换图标是在iOS 10.3以上才可以使用,所以要注意判断系统版本

setAlternateIconName: 如果参数nil可以重置为应用原始图标


- (void)touchesBegan:(NSSet<UITouch *&gt; *)touches withEvent:(UIEvent *)event {
    
    
    [self changeAppIconWithName:@"AppIcon1"];
    
    
}


- (void)changeAppIconWithName:(NSString *)iconName {
    
    if (@available(iOS 10.3, *)) {
        
        if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
            return;
        }
        
        if ([iconName isEqualToString:@""]) {
            //传nil可重置为原始icon
            iconName = nil;
        }
        
        [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
            if (error) {
                NSLog(@"更换app图标发生错误了 : %@",error);
            }else{
                NSLog(@"更换成功");
            }
        }];
        
    } else {
        NSLog(@"版本太低了");
    }
    
}

Swift代码操作如下

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        self.changeAppIcon(iconName: "AppIcon1")
    }
    
    func changeAppIcon(iconName: String?) {
        if #available(iOS 10.3, *) {
            
            if UIApplication.shared.supportsAlternateIcons == false {
                
                return;
            }
            
            //iconName 如果传nil 可以重置为原始icon
            UIApplication.shared.setAlternateIconName(iconName) { error in
                
                if error != nil {
                    print("更换app图标发生错误了" + "(error.debugDescription)")
                } else {
                    print("替换icon成功")
                }
            }
            
        } else {
            
            print("系统版本太低了")
            
        }
        
    }

提示动态替换图标成功如下

在这里插入图片描述

如何无感替换应用图标

运行runtime下用Method swizzling弹框方法进行捕捉替换,可以用户无感的情况下替换图标

一个UIViewControllerCategory结合+ (void)load 自动执行加载 Method swizzling 方法替换

Objective-C具体代码操作如下

#import "UIViewController+Present.h"
#import <objc/runtime.h>

@implementation UIViewController (Present)


+ (void)load {
    
    static dispatch_once_t onceToken;
    dispatch_once(&amp;onceToken, ^{
        
        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)dy_presentViewController:(UIViewController*)viewControllerToPresent animated:(BOOL)flag completion:(void(^)(void))completion {
    
    if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
        
        UIAlertController *alertController = (UIAlertController*)viewControllerToPresent;
        
        if (alertController.title == nil &amp;&amp; alertController.message == nil) {
            
            NSLog(@"替换图标操作");
            return;
            
        } else {
            
            [self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
            return;
            
        }
        
    }
    
    [self dy_presentViewController:viewControllerToPresent animated:flag completion:completion];
    
}

@end

Swift代码操作如下

一个UIViewController扩展方法

extension UIViewController {
    
    public class func initializeMethod() {
        
        let presentSelector = #selector(UIViewController.present(_:animated:completion:))
        let swizzledPresentSelector = #selector(UIViewController.customPresent(_:animated:completion:))
        
        let presentMethod = class_getInstanceMethod(self, presentSelector)
        let swizzledPresentMethod = class_getInstanceMethod(self, swizzledPresentSelector)
        
        let didAddPresentMethod: Bool = class_addMethod(self, presentSelector, method_getImplementation(swizzledPresentMethod!), method_getTypeEncoding(presentMethod!))
        
        if didAddPresentMethod {
            class_replaceMethod(self, swizzledPresentSelector, method_getImplementation(presentMethod!), method_getTypeEncoding(presentMethod!))
        } else {
            method_exchangeImplementations(presentMethod!, swizzledPresentMethod!)
        }
    }
    
    
    @objc func customPresent(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
        
        if viewControllerToPresent is UIAlertController {
            
            
            if let alertController = viewControllerToPresent as? UIAlertController {
                
                if alertController.title == nil && alertController.message == nil {
                    
                    print("替换图标操作")
                    return
                } else {
                    
                    self .customPresent(viewControllerToPresent, animated: flag, completion: completion)
                    return
                }
            }
            
        }
        
        self .customPresent(viewControllerToPresent, animated: flag, completion: completion)
        
    }
    
}

应用启动方法中执行 Method swizzling初始化方法

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        UIViewController.initializeMethod()
        
        return true
    }

以上是笔者在工作中遇到的替换图标需求实现后的简单总结,亲测有效!!!

原文地址:https://blog.csdn.net/Locationluqc/article/details/127680353

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_17665.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注