本文首发于个人博客
前言
- 我们日常使用App中,只有中文就够了,然而如果我们的App是面向国际化的,那么多语言就必不可少。本文整理了在iOS中多语言的实现。
准备工作
添加支持的语言
- 选择工程,在info下面的
Localizations
中,点击加号按钮,添加支持的语言
建立strings文件
- 方法1.选择一个
storyboard
,例如默认的Main.storyboard,
在Localization
栏中勾选支持的语言。系统就会生成对应的文件。 - 方法2.我们直接新建
strings
资源文件。在该文件的File Inspecter
的Localizatio
n栏中勾选支持的语言。
准备对应文案
- 例如在
Localizable.strings(English)
中,
"消息" = "Messages";
"搜索" = " Search";
实现
- 思路:
- 偏好设置中存储我们设置的语言,默认是简体中文
- 当我们切换多语言的时候,更改偏好设置中存储的语言
- 显示的时候,传入key。
- 如果设置了其他语言,就根据对应的bundle中的key取出对应value来显示
切换多语言的实现
定义宏
- 定义多语言的宏,如下,定义了三种宏,分别是简体中文,繁体中文,英文,韩文
#define Chinese_Simple @"zh-Hans"
#define Chinese_Traditional @"zh-Hant"
#define English_US @"en"
#define Korean @"ko"
定义偏好设置的文件名称
#define Language_Key @"eagle_languageKey"
设置多语言
/// 设置多语言
/// @param language 语言
- (void)setNewLanguage:(NSString *)language
{
NSString * setLanguage = [[NSUserDefaults standardUserDefaults] objectForKey:Language_Key];
if ([language isEqualToString:setLanguage]) {
return;
}
// 简体中文
else if ([language isEqualToString:Chinese_Simple]) {
[[NSUserDefaults standardUserDefaults] setObject:Chinese_Simple forKey:Language_Key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// 繁体中文
else if ([language isEqualToString:Chinese_Traditional]) {
[[NSUserDefaults standardUserDefaults] setObject:Chinese_Traditional forKey:Language_Key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// 英文
else if ([language isEqualToString:English_US]) {
[[NSUserDefaults standardUserDefaults] setObject:English_US forKey:Language_Key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
// 韩语
else if ([language isEqualToString:Korean]) {
[[NSUserDefaults standardUserDefaults] setObject:Korean forKey:Language_Key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
使用
#define languageStringWithKey(key) [[LanguageTools sharedInstance] getStringForKey:key]
NSString *title = languageStringWithKey(@"确定");
具体实现如下,先偏好设置存储的当前语言获取对应bundle,然后拿到这个bundle之后,根据key找到对应的值。
// 根据语言名获取bundle
- (NSBundle *)bundle
{
NSString * setLanguage = [[NSUserDefaults standardUserDefaults] objectForKey:Language_Key];
//默认是简体中文
if (setLanguage == nil || [setLanguage isEqualToString:@"zh-Hans-CN"]) {
setLanguage = Chinese_Simple;
}
NSString * bundlePath = [[NSBundle mainBundle] pathForResource:setLanguage ofType:@"lproj"];
return [NSBundle bundleWithPath:bundlePath];
}
// 根据key获取value
- (NSString *)getStringForKey:(NSString *)key
{
NSBundle * bundle = [[LanguageTools sharedInstance] bundle];
if (bundle) {
NSString * valueString = NSLocalizedStringFromTableInBundle(key, @"Localizable", bundle, @"HelloWord");
if (!KCNSSTRING_ISEMPTY(valueString)) {
return valueString;
}
DDLogInfo(@"\n********** have not add key **********\n \"%@\" = \"%@\" \n****************************",key,key);
return NSLocalizedString(key, @"HelloWord");
}
return NSLocalizedString(key, @"HelloWord");
}
NSLocalizedString
-
NSLocalizedString
是一个定义在NSBundle.h
中的宏,用途是寻找当前系统语言对应的Localizable.strings
文件中的某个key
的值。 -
第一个参数是
key
的名字,第二个参数是对这个“键值对”的注释,在用genstrings
工具生成Loclizable.strings
文件时会自动加上去。例如上面代码中的HelloWord
就是注释。 -
NSLocalizedString
系列的四个宏,其实最终都是调用了[bundle localizedStringForKey:(key) value:(val) table:(tbl)]
。根据我们的自定义程度不同可以选择不同的宏。
#define NSLocalizedString(key, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) \
[bundle localizedStringForKey:(key) value:(val) table:(tbl)]
上面基本就是实现一个可控的多语言版本的实现过程。