应用内切换语言

思路

主要就是利用runtime hook系统的方法,宏定义为NSLocalizedString(key, comment),方法为[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil],设置语言的时候传入正确的语言代码并找到相应的bundle,进而得到想要的字符串。当然已经显示的页面还要自己处理页面的刷新,比如更新rootViewController。

#import <Foundation/Foundation.h>

@interface NSBundle (Language)

+ (void)setLangage:(NSString *)language;//zh-Hans,en,zh-Hant...

@end
#import "NSBundle+Language.h"
#import <objc/runtime.h>

static NSString *languageKey = @"chosenLanguage";

@implementation NSBundle (Language)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector = @selector(localizedStringForKey:value:table:);
        SEL swizzledSelector = @selector(yx_localizedStringForKey:value:table:);
        
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (didAddMethod) {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (NSString *)yx_localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName {
    NSString *chosenLanguage = [[NSUserDefaults standardUserDefaults] objectForKey:languageKey];
    chosenLanguage = chosenLanguage ? chosenLanguage: @"Base";
    NSBundle *chosenBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:chosenLanguage ofType:@"lproj"]];
    chosenBundle = chosenBundle ? chosenBundle: NSBundle.mainBundle;
    NSString *result = [chosenBundle yx_localizedStringForKey:key value:value table:tableName];
    return result;
}

+ (void)setLangage:(NSString *)language {
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:languageKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容