当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了。当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局、交互效果的转变,如微信,微博,QQ这类应用都有着切换语言的功能。
iOS常用的国际化流程
1.建立strings文件。2.在Localization勾选支持的语言,在不同的后缀的同文件名的strings中设置标题。3.使用NSLocalizedStringFromTable(key, tbl, comment) 这个宏取出key对应的value。
这样的做法方便快捷,但有一些缺点。1.完全是根据手机系统设置的语言来进行国际化的。2.手机系统语言更改后,需将App Kill后,重新进入才有改变。可以看出给用户带来很大的不便,一些用户根本不知道如何设置语言,而且还去跳出应用,再Kill应用。我们需要的是应用内切换语言,所见即所得。应用内切换语言
先看下微信的做法
关键
1.NSBundle
An NSBundle object represents a location in the file system that groups code and resources that can be used in a program.NSBundle objects locate program resources, dynamically load and unload executable code, and assist in localization. You build a bundle in Xcode using one of these project types: Application, Framework, plug-ins.
2.宏 NSLocalizedStringFromTableInBundle
它的定义
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
Returns a localized version of a string.The key for a string in the specified table.从指定的bundle里的table中返回对应key的值。上面两点就是应用内切换的关键先浏览下Demo架构 建立FGLanguageTool类来管理语言的切换,因为许多地方都要用到,将其设计为单例。并定义一个宏来加载设定的语言。
#define FGGetStringWithKeyFromTable(key, tbl) [[FGLanguageTool sharedInstance] getStringForKey:key withTable:tbl]#import@interface FGLanguageTool : NSObject +(id)sharedInstance; /** * 返回table中指定的key的值 * * @param key key * @param table table * * @return 返回table中指定的key的值 */ -(NSString *)getStringForKey:(NSString *)key withTable:(NSString *)table; /** * 改变当前语言 */ -(void)changeNowLanguage; /** * 设置新的语言 * * @param language 新语言 */ -(void)setNewLanguage:(NSString*)language; @end
对应的.m文件
#define CNS @"zh-Hans"#define EN @"en"#define LANGUAGE_SET @"langeuageset" #import "AppDelegate.h" #import "FGLanguageTool.h" static FGLanguageTool *sharedModel; @interface FGLanguageTool() @property(nonatomic,strong)NSBundle *bundle; @property(nonatomic,copy)NSString *language; @end @implementation FGLanguageTool +(id)sharedInstance { if (!sharedModel) { sharedModel = [[FGLanguageTool alloc]init]; } return sharedModel; } -(instancetype)init { self = [super init]; if (self) { [self initLanguage]; } return self; } -(void)initLanguage { NSString *tmp = [[NSUserDefaults standardUserDefaults]objectForKey:LANGUAGE_SET]; NSString *path; //默认是中文 if (!tmp) { tmp = CNS; } else { tmp = EN; } self.language = tmp; path = [[NSBundle mainBundle]pathForResource:self.language ofType:@"lproj"]; self.bundle = [NSBundle bundleWithPath:path]; } -(NSString *)getStringForKey:(NSString *)key withTable:(NSString *)table { if (self.bundle) { return NSLocalizedStringFromTableInBundle(key, table, self.bundle, @""); } return NSLocalizedStringFromTable(key, table, @""); } -(void)changeNowLanguage { if ([self.language isEqualToString:EN]) { [self setNewLanguage:CNS]; } else { [self setNewLanguage:EN]; } } -(void)setNewLanguage:(NSString *)language { if ([language isEqualToString:self.language]) { return; } if ([language isEqualToString:EN] || [language isEqualToString:CNS]) { NSString *path = [[NSBundle mainBundle]pathForResource:language ofType:@"lproj"]; self.bundle = [NSBundle bundleWithPath:path]; } self.language = language; [[NSUserDefaults standardUserDefaults]setObject:language forKey:LANGUAGE_SET]; [[NSUserDefaults standardUserDefaults]synchronize]; [self resetRootViewController]; } //重新设置 -(void)resetRootViewController { AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; UINavigationController *rootNav = [storyBoard instantiateViewControllerWithIdentifier:@"rootnav"]; UINavigationController *personNav = [storyBoard instantiateViewControllerWithIdentifier:@"personnav"]; UITabBarController *tabVC = (UITabBarController*)appDelegate.window.rootViewController; tabVC.viewControllers = @[rootNav,personNav]; } @end
在ViewController里使用下面类似的方式进行赋值
self.navigationItem.title = FGGetStringWithKeyFromTable(@"RootTitle", @"Main"); self.languageLabel.text = FGGetStringWithKeyFromTable(@"NowLanguage", @"Person");
"Main","Person"就是strings文件的名字。"RootTitle"和"NowLanguage"就是key。
"NowLanguage"="English";
"PersonTitle"="Person";
Person.strings(Chinese(Simplified))文件中内容
"NowLanguage"="中文";
"PersonTitle"="个人";
即在不同的相同文件名不同后缀名文件中设置不同的value。
几个关键点
1,当我们设置支持多语言后创建多语言文件后,工程文件结构中多了一些文件夹,Base是工程默认的,而后面的两个就是我们设置多语言后自动生成的,对应相应的英文和简体中文。分别以en和zh-Hans开头,所以FGLanguageTool中将中文和英文定义为en和zh-Hans来加载对应的bundle。
里面存放的就是对应的strings文件
2.NSLocalizedStringFromTableInBundle,从指定的bundle中去指定table的key的值。
3.更改语言后,重新设置rootViewController,使得可以重新加载语言。最终效果