多语言适配 -- 手动切换设备语言

Xcode 的新建工程默认语言为英文,可如果你想要在软件内切换语言,为软件添加多种语言适配,就需要另一番设置了。

关于 NSBundle

在开始正式文章之前你或许应当先搞明白 NSBundle 是什么东西。

Bundle 是一个目录,其中包含了在程序会使用到的资源,包含了如图像、声音、程序中需要用到的文件,甚至是编译好的代码等等。而在实现软件内配置语言的时候就是通过 Bundle 的路径去获取配置文件,根据这个配置文件取出对应的字体渲染到 view 上。

当然,配置程序语言只是 Bundle 的一种用途。还可以用 Bundle 去获取工程中 info.plist 的详细信息,比如:

// 获取版本号:Bundle Short Version
NSString *shortVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
// 获取版本号:Bundle version
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
// 获取应用标识:Bundle identifier
NSString *bundleIdentifier = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
// 获取应用名称:Bundle display name
NSString *bundleDisplayName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
// 获取Bundle name
NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
// 获取 app 包路径
NSString *path = [[NSBundle mainBundle] bundlePath];
// 获取 app 资源目录路径
NSString *resPath = [[NSBundle mainBundle] resourcePath];
...

大概明白 NSBundle 是怎么回事了吧,接下来就正式开始应用程序语言本地化及应用内语言设置。

配置 Project

添加语言

如下图,点击 PROJECT -> info -> Localizations 这里默认只有 English 点击下方的加号可以添加你想要的语言,比如这里添加的中文 Chinese(Simplifid) 。

注意: zh-Hans 是简体中文, zh-Hant 是繁体中文。

Paste_Image.png

新建 .strings 配置文件

1、Command + N 新建 Strings File 文件,命令为 Localizable ,会生成一份 Localizable.strings 文件。

2、选中Localizable.strings 文件,如下图操作,点击 Localize... 按钮,左侧弹框中选择语言。

Snip20170101_8.png

3、之后右侧会如下图显示,勾选上你想要的语言即可(Base 无用)

Paste_Image.png

4、当勾选两门语言后,会发现Localizable.strings 文件可以展开并存在两个配置文件,一份英文,一份中文。
分别在两个文件内输入对应的语言,比如在英文文件里输入:

"收录" = "Collection";
"订阅" = "Subscription";
"我的" = "Mine";

中文文件里输入:

"收录" = "收录";
"订阅" = "订阅";
"我的" = "我的";

前边对应 键(key) ,后边对各个语言的 值(value)。看后面的 使用方法 就会明白了。

至此,对工程的配置已经完成。接下来要做的就是获取软件语言、设置语言、监听语言改变。。。

创建多语言设置工具类

因为该工具类比较简单,直接将代码贴出来吧,后面会介绍一些注意事项。因为是一个继承于 NSObject 的工具类,都是使用类方法实现功能,以便类名直接调用。

头文件.h

//
//  PALocalizable.h
//  PictureAir
//
//  Created by Nick on 2016/11/18.
//  Copyright © 2016年 Nick. All rights reserved.
//  语言本地化

#import <Foundation/Foundation.h>

@interface PALocalizable : NSObject

/** 获取当前资源文件 */
+ (NSBundle *)bundle;

/** 初使化软件语言 */
+ (void)initAppLanguage;

/** 获取应用当前语言 */
+ (NSString *)loadAppLanguage;

/** 设置软件语言 */
+ (void)setAppLanguage:(NSString *)language;

@end     

实现文件.m

//
//  PALocalizable.m
//  PictureAir
//
//  Created by Nick on 2016/11/18.
//  Copyright © 2016年 Nick. All rights reserved.
//

#import "PALocalizable.h"

@implementation PALocalizable

static NSBundle *bundle = nil;

/** 获取当前资源文件 */
+ (NSBundle *)bundle {
    return bundle;
}

/** 初使化软件语言 */
+ (void)initAppLanguage {
    if (![PADataCache loadCache:kAppLanguage]) {
        NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
        if ([language hasPrefix:@"zh-Hans"]) {
            [PADataCache setCache:kChineseLanguage forKey:kAppLanguage];
        }
        if ([language hasPrefix:@"en"]) {
            [PADataCache setCache:kEnglishLanguage forKey:kAppLanguage];
        }
    }
    
    NSString *path = [[NSBundle mainBundle] pathForResource:[PADataCache loadCache:kAppLanguage] ofType:@"lproj"];
    bundle = [NSBundle bundleWithPath:path];
}

/** 获取应用当前语言 */
+ (NSString *)loadAppLanguage {
    return [PADataCache loadCache:kAppLanguage];
}

/** 设置软件语言 */
+ (void)setAppLanguage:(NSString *)language {
    NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"];
    bundle = [NSBundle bundleWithPath:path];
    
    [PADataCache setCache:language forKey:kAppLanguage];
}

使用方法:

1、在 AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法里初始化该工具类,并监听通知:


/** 设置软件语言环境 */
[PALocalizable initAppLanguage];

/** 监控语言切换 */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageChange:) name:PANotificationLanguageChanged object:nil];

2、记得在 - (void)applicationWillTerminate:(UIApplication *)application方法里删除通知:

[[NSNotificationCenter defaultCenter] removeObserver:self name:PANotificationLanguageChanged object:nil];

3、实现通知方法:

- (void)languageChange:(NSNotification *)note{
    // 在该方法里实现重新初始化 rootViewController 的行为,并且所有带有文字的页面都要重新渲染
    // 比如:[UIApplication sharedApplication].keyWindow.rootViewController = ...;
}

4、使用 PALocalizedString(<#key#>)方法 给所有文字添加本地化语言方法:

label.text = PALocalizedString(@"收录");
[button setTitle:PALocalizedString(@"订阅") forState:UIControlStateNormal];
...

5、更改语言方法:

// 设置中文
[PALocalizable setAppLanguage: @"zh-CN"];

// 设置英文
[PALocalizable setAppLanguage:@"en-US"];

到此应用程序语言本地化及应用内语言设置的功能就已经可以实现了。

使用时还有以下几个注意点

切换语言后控件没有刷新

语言更改后,要重新渲染view,因为字体是 PALocalizedString(<#key#>) 这个方法从 .strings 配置文件里取出来的,更改语言后必须重新取一次。

1、切换语言功能一般在「我的」页面 push 出来的某一级页面里,如果rootViewControllerUITabBarController时,切换语言后 UITabBarItemTitle 并不会刷新,这个时候需要在切换语言时发送一个语言改变的通知并在 UITabBarController里接收去刷新

- (void)languageChange:(NSNotification *)note { 

         for (int i = 0; i < self.tabBar.items.count; i++) {
             UITabBarItem *item = self.tabBar.items[i];
             if (i == 0) {
                 [item setTitle:PALocalizedString(@"photos_home_title")];
             }
             if (i == 2) {
                 [item setTitle:PALocalizedString(@"albums_home_title")];
             }
         }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容