设置AppleLanguages字段,只会在下次启动App才会生效,在App启动后就已经生成了一个Bundle,里面识别好了对应着AppleLanguages的国际化文件,在App运行期间设置这个字段,是不生效的,所以我们去修改这个Bundle,写一个NSBundle的扩展。
.h
#import <Foundation/Foundation.h>
@interface NSBundle (Language)
+ (void)setLanguage:(NSString *)language;
@end
.m
#import "NSBundle+Language.h"
#import <objc/runtime.h>
static const char _bundle = 0;
@interface BundleEx : NSBundle
@end
@implementation BundleEx
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
NSBundle *bundle = objc_getAssociatedObject(self, &_bundle);
return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}
@end
@implementation NSBundle (Language)
+ (void)setLanguage:(NSString *)language {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
object_setClass([NSBundle mainBundle], [BundleEx class]);
});
objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
切换语言页面
#import "ViewController3.h"
#import "ZHTabBarController.h"
#import "NSBundle+Language.h"
@interface ViewController3 ()
@property (weak, nonatomic) IBOutlet UIButton *chineseBtn;
@property (weak, nonatomic) IBOutlet UIButton *englishBtn;
@end
@implementation ViewController3
- (void)viewDidLoad {
[super viewDidLoad];
[self.chineseBtn setTitle:NSLocalizedString(@"btn1", nil) forState:UIControlStateNormal];
[self.englishBtn setTitle:NSLocalizedString(@"btn2", nil) forState:UIControlStateNormal];
}
- (IBAction)chineseBtnAction:(id)sender {
[self changeLanguageTo:@"zh-Hans"];
}
- (IBAction)englishBtnAction:(id)sender {
[self changeLanguageTo:@"en"];
}
- (void)changeLanguageTo:(NSString *)language {
// 设置语言
[NSBundle setLanguage:language];
// 然后将设置好的语言存储好,下次进来直接加载
[[NSUserDefaults standardUserDefaults] setObject:language forKey:@"myLanguage"];
[[NSUserDefaults standardUserDefaults] synchronize];
// 我们要把系统windown的rootViewController替换掉
ZHTabBarController *tab = [[ZHTabBarController alloc] init];
[UIApplication sharedApplication].keyWindow.rootViewController = tab;
// 跳转到设置页
tab.selectedIndex = 2;
}
appDelegate中的方法修改为:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"myLanguage"] && ![[[NSUserDefaults standardUserDefaults] objectForKey:@"myLanguage"] isEqualToString:@""]) {
[NSBundle setLanguage:[[NSUserDefaults standardUserDefaults] objectForKey:@"myLanguage"]];
}
// 创建主页面
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [[ZHTabBarController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}