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

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 是繁体中文。

多语言适配 -- 手动切换设备语言_第1张图片
Paste_Image.png

新建 .strings 配置文件

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

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

多语言适配 -- 手动切换设备语言_第2张图片
Snip20170101_8.png

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

多语言适配 -- 手动切换设备语言_第3张图片
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 

@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")];
             }
         }
}

你可能感兴趣的:(多语言适配 -- 手动切换设备语言)