Mr.C/文
天下惟庸人无咎无誉 —— 梁启超
前言
在大航海时期,人类实现了物理意义上的全球化,东西方物质和文化随着人类大规模的物理迁移而实现了全方面的交流。
在今天互联网时期,我们将会实现数字意义上的全球化,今天我们可以坐在中国一个小城镇,享受着美国顶级学府的教育(哈佛、MIT、斯坦福 and so on...)。
作为一名开发者,从个人和职业发展的角度,都应要更上时代的脚步(那些跟不上时代的,终将被淘汰),在我们的APP中考虑国际化问题(套用一句老话:中国都加入WTO了,我们要跟国际接轨了)。
本文记录了一种iOS APP语言切换的方法,给有需要的小伙伴们作为参考。
重要的事情说三遍:
本文提供的方法不是根据系统语言设定APP语言,而是在APP内实现按键切换
本文提供的方法不是根据系统语言设定APP语言,而是在APP内实现按键切换
本文提供的方法不是根据系统语言设定APP语言,而是在APP内实现按键切换
系统和版本
- Mac 10.11.4(OS X EI Capitan)
- Xcode 7.3
- iOS7.0+
流程图
Demo
在例子中,我们需要两个类与一个文字资源:
- ViewController 是用于展示界面
- InternationalT 用于切换和保存当前所使用的语言资源
- StringBundle 保存文字的资源
InternationalT 类
在InternationalT 类中,我们需要实现以下四个接口:
+(NSBundle *)bundle;//获取当前资源文件
+(void)initUserLanguage;//初始化语言文件
+(NSString *)userLanguage;//获取当前所使用语言
+(void)setUserlanguage:(NSString *)language;//设置当前语言
InternationalT 类实现:
static NSString *userLanguage;//当前使用语言
static NSBundle *bundle = nil;
+ ( NSBundle * )bundle{
return bundle;//返回当前的bundle
}
+(void)initUserLanguage{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSString *string = [def valueForKey:@"userLanguage"];
userLanguage = string;
if(string.length == 0){
//获取系统当前语言版本(简体中文zh-Hans,繁体中文zh-Hant,英文en)
NSArray* languages = [def objectForKey:@"AppleLanguages"];
NSString *current = [languages objectAtIndex:0];
string = current;
[def setValue:current forKey:@"userLanguage"];
[def synchronize];//将设置保存到文件中
}
//获取文件路径
NSString *path = [[NSBundle mainBundle] pathForResource:string ofType:@"lproj"];
bundle = [NSBundle bundleWithPath:path];//生成bundle
}
+(NSString *)userLanguage;//获取应用当前语言
{
return userLanguage;
}
+(void)setUserlanguage:(NSString *)language{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
//根据语言的值更新路径
NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj" ];
//获取新的bundle
bundle = [NSBundle bundleWithPath:path];
userLanguage = language;
//保存至文件
[def setValue:language forKey:@"userLanguage"];
[def synchronize];
//改变完成之后发送通知,在需要刷新的页面接收该通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeLanguage" object:nil];
}
在InternationalT 类中,有以下几点需要注意:
- 在获取系统语言的时候,同一语种会因为使用不同国家或地区不同而返回不一样值,所以我们在同一语种时,建议通过关键字判断(如果需要优化到某一国家或地区的话,工作量略大,如中文有6种,英文有几十种)。
- 在完成设置后,我们会通过通知的方式告知APP中需要刷新信息的界面,所以我们需要在有信息刷新的界面接收该通知,并处理。
ViewController
ViewController 是一个演示界面,在本Demo中该界面的作用有两个:
- 作为语言切换按钮所在界面
- 根据所切换的语言刷新自身界面语言
ViewController 主要实现以下几个方法:
- (void)viewDidLoad
{
//注册通知,用于接收改变语言的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeLanguage) name:@"changeLanguage" object:nil];
[International initUserLanguage];//初始化应用语言
NSBundle *bundle = [International bundle];
NSString *inviteMsg = [bundle localizedStringForKey:@"Text" value:nil table:@"StringBundle"];
NSString *buttonInfo = [bundle localizedStringForKey:@"buttonInfo" value:nil table:@"StringBundle"];//table为StringBundle.string的文件名
[_btChange setTitle:buttonInfo forState:UIControlStateNormal];
_inviteLabel.text = inviteMsg;
[super viewDidLoad];
}
//更改语言设置
- (IBAction)changeLanguage:(id)sender {
NSString *lan = [International userLanguage];
if([lan isEqualToString:@"en"]){//判断当前的语言,进行改变
[International setUserlanguage:@"zh-Hans"];
}else{
[International setUserlanguage:@"en"];
}
}
//接收到通知后的处理方法
-(void)changeLanguage{
[_btChange setTitle:[[International bundle] localizedStringForKey:@"buttonInfo" value:nil table:@"StringBundle"] forState:UIControlStateNormal];
_inviteLabel.text =[[International bundle] localizedStringForKey:@"Text" value:nil table:@"StringBundle"];
}
stringBundle
stringBundle是用来存放我们字符串的文件,我们可以利用Xcode提供的功能,很方便的实现国际化:
1、创建一个string类型的资源文件
2、将stringBundle文件本地化:
3、在系统中添加本地化文件
4、添加成功后可以看到在该文件下有各语言的配置文件
5、在各语言文件下添加key和value,如:
在chinese文件中添加:
“buttonInfo” = “语言切换”/中文/
在English文件中添加:
“buttonInfo” = “Change Language”/英文/
6、在切换界面中使用切换(如上节所说,添加通知,并设置通知处理函数):
-(void)changeLanguage{
[_btChange setTitle:[[International bundle] localizedStringForKey:@"buttonInfo" value:nil table:@"StringBundle"] forState:UIControlStateNormal];
}
End
本文参考链接:http://blog.csdn.net/x32sky/article/details/39031025 。
本文所给出的代码是在该链接文章中的基础上进行改进的,在此感谢该原文作者。