思路
主要就是利用runtime hook系統(tǒng)的方法,宏定義為NSLocalizedString(key, comment)臼勉,方法為[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil],設(shè)置語言的時(shí)候傳入正確的語言代碼并找到相應(yīng)的bundle,進(jìn)而得到想要的字符串枉侧。當(dāng)然已經(jīng)顯示的頁面還要自己處理頁面的刷新屉凯,比如更新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