1.前言
自己负责的项目需要做国际化,并且要求应用内部切换语言。这个是可以做到的,也并不难,可以直接戳Github看一下
https://github.com/leo90821/LocaliztionStringExchange
2.实现原理
原理比较简单,利用NSBundle切换语言包,主要利用NSBundle的方法
- localizedStringForKey:value:table: 进行本地字符串的切换
3.实现代码
1)业务逻辑
头文件
#import <Foundation/Foundation.h> #define USER_DEFAULT_STRING @"userLanguage" #define APPLE_LANGUAGES @"AppleLanguages" /** * App BLL **/ @interface BLL : NSObject /** * BLL single **/ + (instancetype)currentLogic; /** * App bundle **/ + (NSBundle *)bundle; /** * 初始化语言 **/ - (void)initUserLanguage; /** * 获得当前语言 **/ - (NSString *)getCurrentLanguage; /** * 设置语言 **/ - (void)setUserLanguageWithLanguage:(NSString *)language; @end
实现文件
#import "BLL.h" @implementation BLL static NSBundle *bundle = nil; - (instancetype)init { self = [super init]; return self; } + (instancetype)currentLogic { static BLL *logic = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ logic = [[BLL alloc] init]; }); return logic; } + (NSBundle *)bundle { return bundle; } /** * 初始化语言 **/ - (void)initUserLanguage { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; NSString *string = [userDefault valueForKey:USER_DEFAULT_STRING]; if (string.length == 0) { NSArray *languages = [userDefault objectForKey:APPLE_LANGUAGES]; NSString *current = [languages objectAtIndex:0]; string = current; [userDefault setValue:string forKey:USER_DEFAULT_STRING]; [userDefault synchronize]; } NSString *path = [[NSBundle mainBundle] pathForResource:string ofType:@"lproj"]; bundle = [NSBundle bundleWithPath:path]; } /** * 获得当前语言 **/ - (NSString *)getCurrentLanguage { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; NSString *language = [userDefault valueForKey:USER_DEFAULT_STRING]; return language; } /** * 设置语言 **/ - (void)setUserLanguageWithLanguage:(NSString *)language { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]; bundle = [NSBundle bundleWithPath:path]; [userDefault setValue:language forKey:USER_DEFAULT_STRING]; [userDefault synchronize]; } @end
2)视图控制器
#import <UIKit/UIKit.h> #define NOTIFICATION_CHANGE_LANGUAGE @"ChangeLanguage" @interface ViewController : UIViewController @end
#import "ViewController.h" #import "BLL.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *tip; - (IBAction)changeLanguage:(id)sender; @property (weak, nonatomic) IBOutlet UIButton *button; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self.button setTitle:NSLocalizedStringFromTable(@"Change", @"MyString", nil) forState:UIControlStateNormal]; self.tip.text = NSLocalizedStringFromTable(@"Hello", @"MyString", nil); } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self addObservers]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self removeObservers]; } - (void)addObservers { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshUI) name:NOTIFICATION_CHANGE_LANGUAGE object:nil]; } - (void)removeObservers { [[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIFICATION_CHANGE_LANGUAGE object:nil]; } - (void)refreshUI { [self.button setTitle:[[BLL bundle] localizedStringForKey:@"Change" value:nil table:@"MyString"] forState:UIControlStateNormal]; self.tip.text = [[BLL bundle] localizedStringForKey:@"Hello" value:nil table:@"MyString"]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)changeLanguage:(id)sender { NSString *language = [[BLL currentLogic] getCurrentLanguage]; if ([language rangeOfString:@"en"].location != NSNotFound) { [[BLL currentLogic] setUserLanguageWithLanguage:@"zh-Hans"]; } else { [[BLL currentLogic] setUserLanguageWithLanguage:@"en"]; } [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CHANGE_LANGUAGE object:nil ]; } @end
4.小结
原理比较简单,利用NSBundle切换语言包,主要利用NSBundle的方法
- localizedStringForKey:value:table: 进行本地字符串的切换,最麻烦的是刷新每个页面都需要设置消息观察者,这个就比较蛋疼。有没有好的方法,欢迎留言交流。