实现iOS中的多语言切换

3,278 阅读3分钟

本文首发于个人博客

前言

  • 我们日常使用App中,只有中文就够了,然而如果我们的App是面向国际化的,那么多语言就必不可少。本文整理了在iOS中多语言的实现。

准备工作

添加支持的语言

  • 选择工程,在info下面的Localizations中,点击加号按钮,添加支持的语言

建立strings文件

  • 方法1.选择一个storyboard,例如默认的Main.storyboard,Localization栏中勾选支持的语言。系统就会生成对应的文件。
  • 方法2.我们直接新建strings资源文件。在该文件的File InspecterLocalization栏中勾选支持的语言。

准备对应文案

  • 例如在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)]

上面基本就是实现一个可控的多语言版本的实现过程。