美文网首页iOS Crazies
iOS 多语言全局适配

iOS 多语言全局适配

作者: hehtao | 来源:发表于2018-09-06 14:29 被阅读20次

    本文记录iOS 多语言全局适配解决方案,适用于项目中后期快速适配多语言;


    实现思路:runtime method swizzling,拦截UILabel 的setText: 方法、UIViewController 的 setTitle:方法、UINavigationItem 的setTitle:方法;

    一、多语言基本适配:

    该部分请参考:VV木公子 作品:
    3分钟实现iOS语言本地化/国际化(图文详解)!


    二、多语言配置读取:

    NSString  *GlobalLanguePath;
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self  configAppLangue];
    }
    
    -(void)configAppLangue{
        //根据NSUserDefaults的key去取多语言类型, k_AppLaguageKey为与用户相关的 Key
        NSString *laguageType = [[NSUserDefaults standardUserDefaults] objectForKey:k_AppLaguageKey];
        if (laguageType == nil) {  // 如果没有用户偏好则根据系统第一语言配置启动,并且不做偏好设置记录
            NSString *preferredLanguage = [NSLocale preferredLanguages][0];
            if ([preferredLanguage hasPrefix:@"en"]) {
                laguageType = @"en";
            }else{
                laguageType = @"zh-Hans";
            }
        }
        NSLog(@"当前语言环境:%@",laguageType);
        GlobalLanguePath = [[NSBundle mainBundle] pathForResource:laguageType ofType:@"lproj"];
    }
    

    为了方便使用,pch 来个宏定义:

    // 语言加载路径 全局变量
    extern NSString *GlobalLanguePath;
    #define k_LangueKey(key) [[NSBundle bundleWithPath:GlobalLanguePath] localizedStringForKey:key value:nil table:@"Localizable"]
    

    使用如下:

    UILabel *label = [UILabel new];
    label.text = k_LangueKey(@"你所配置的key");
    
    一点注意: 如若手动切换语言环境,而不是跟随系统语言环境变化,则在语言切换之后重新初始化 window.rootViewController ,然后代码 push 到切换语言之前的 controller(如XXSettingViewController) 即可;

    三、全局修改方式:

    到此处可以使用 k_LangueKey() 一处一处修改了,然后在项目后期何其麻烦又是何其繁琐,所以自然想到拦截 UILabel 的 setText 方法:

    #import "NSObject+swapMethod.h"
    #import <UIKit/UIKit.h>
    @implementation UILabel (Langues)
    
    +(void)load{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self swapSelector:@selector(setText:) toSelector:@selector(langues_setText:)];
        });
    }
    
    -(void)langues_setText:(NSString *)text{
        [self langues_setText:k_LangueKey(text)];
    }
    
    @end
    
    

    然而,此时也许你会发现 导航栏 title 和 tabbarItem title 全变黑了,So ...

    #import "NSObject+swapMethod.h"
    
    @implementation UINavigationItem (Langues)
    
    +(void)load{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self swapSelector:@selector(setTitle:) toSelector:@selector(langues_setTitle:)];
        });
    }
    
    -(void)langues_setTitle:(NSString *)title{
        [self langues_setTitle:k_LangueKey(title)];
    }
    @end
    
    
    
    #import "NSObject+swapMethod.h"
    @implementation UIViewController (Langues)
    
    +(void)load{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self swapSelector:@selector(setTitle:) toSelector:@selector(langues_setTitle:)];
        });
    }
    
    -(void)langues_setTitle:(NSString *)title{
        [self langues_setTitle:k_LangueKey(title)];
    }
    
    @end
    

    最后附上 swapSelector:toSelector方法:

    #import "NSObject+swapMethod.h"
    #import <objc/runtime.h>
    
    @implementation NSObject (swapMethod)
    +(void)swapSelector:(SEL)systemSelector toSelector:(SEL)customSelector{
        
            SEL org_Selector = systemSelector;
            SEL new_Selector  = customSelector;
            
            Method org_method = class_getInstanceMethod([self class], org_Selector);
            Method new_method  = class_getInstanceMethod([self class], new_Selector);
            
            BOOL isAdd = class_addMethod(self, org_Selector, method_getImplementation(new_method), method_getTypeEncoding(new_method));
            if (isAdd) {
                class_replaceMethod(self, customSelector, method_getImplementation(new_method), method_getTypeEncoding(new_method));
            }else{
                method_exchangeImplementations(org_method, new_method);
            }
    }
    @end
    

    So End All

    相关文章

      网友评论

        本文标题:iOS 多语言全局适配

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