前言
在一次项目中,要求在应用内切换语言的需求。如需跟随系统改变语言的,可以参考其他的博客,这里就不多说了
思路
创建一个国际化管理者,通过传递一个key,再根据当前的语言环境,获取对应的value。
实现步骤
1、选择要国际化的语言
进入如下界面后,找到最下面的“+”号,选择要进行国际化的语言
2、创建strings文件
点击strings文件,在右侧工具栏找到Localization,选择要国际化的语种
选择后,就会产生对应的lproj文件,以下是勾选了简体中文和英语后的文件目录
3、创建国际化管理者
LocalizationManager.h
#import <Foundation/Foundation.h>
/// 国际化管理者
@interface LocalizationManager : NSObject
/// 获取当前资源文件
+ (NSBundle *)bundle;
/// 初始化语言文件
+ (void)initUserLanguage;
/// 获取应用当前语言
+ (NSString *)userLanguage;
/// 设置当前语言
+ (void)setUserlanguage:(NSString *)language;
/// 通过Key获得对应的string
+ (NSString *)getStringByKey:(NSString *)key;
@end
LocalizationManager.m
#import "LocalizationManager.h"
#import "AppDelegate.h"
#import "MyTabBarViewController.h"
@implementation LocalizationManager
static NSString *TableName = @"localization";
static NSBundle *bundle = nil;
static NSString *UserLanguage = @"UserLanguage";
+ (NSBundle *)bundle
{
if(!bundle)
{
[self initUserLanguage];
}
return bundle;
}
+ (void)initUserLanguage{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSString *string = [def valueForKey:UserLanguage];
if(string.length == 0)
{
//获取系统当前语言版本(中文zh-Hans,英文en)
NSArray *languages = [NSLocale preferredLanguages];
NSString *current = [languages objectAtIndex:0];
string = [self languageFormat:current];
[def setValue:current forKey:UserLanguage];
[def synchronize];//持久化,不加的话不会保存
}
//获取文件路径
NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:string] ofType:@"lproj"];
bundle = [NSBundle bundleWithPath:path];//生成bundle
}
+ (void)setUserlanguage:(NSString *)language{
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
//1.第一步改变bundle的值
NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:language] ofType:@"lproj" ];
bundle = [NSBundle bundleWithPath:path];
//2.持久化
[def setValue:language forKey:UserLanguage];
[def synchronize];
[self resetRootViewController];
}
+ (NSString *)userLanguage
{
NSString *userLanguage = [[NSUserDefaults standardUserDefaults] objectForKey:UserLanguage];
return userLanguage;
}
+ (NSString *)getStringByKey:(NSString *)key
{
return [[LocalizationManager bundle] localizedStringForKey:key value:nil table:TableName];
}
///语言和语言对应的.lproj的文件夹前缀不一致时在这里做处理
+ (NSString *)languageFormat:(NSString*)language {
if([language rangeOfString:@"zh-Hans"].location != NSNotFound)
{
return @"zh-Hans";
}
else if([language rangeOfString:@"zh-Hant"].location != NSNotFound)
{
return @"zh-Hant";
}
else
{
//字符串查找
if([language rangeOfString:@"-"].location != NSNotFound) {
//除了中文以外的其他语言统一处理@"ru_RU" @"ko_KR"取前面一部分
NSArray *ary = [language componentsSeparatedByString:@"-"];
if (ary.count > 1) {
NSString *str = ary[0];
return str;
}
}
}
return language;
}
//重新设置
+ (void)resetRootViewController
{
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
MyTabBarViewController *tabVC = [[MyTabBarViewController alloc] init];
delegate.window.rootViewController = tabVC;
}
@end
难点解析
一、获取bundle文件
通过getStringByKey去获取对应的语种蚊子
_homeLabel.text = [LocalizationManager getStringByKey:@"home"];
二、切换语言
这里只做了对中英的切换。这里切换我是使用的是直接更改根控制器,从而达到其他界面的文字随之改变。另外一种是使用通知的方法,这个方法可以是可以,但是当控制器一多,通知起来就显示十分麻烦了。微信也是采用直接更改根控制器实现的。
- (IBAction)switch
{
if([[LocalizationManager userLanguage] isEqualToString:@"en"])
{
[LocalizationManager setUserlanguage:@"zh-Hans"];
}
else
{
[LocalizationManager setUserlanguage:@"en"];
}
}