本文會用gif詳細演示如何支持多語言,如何輕松搞定StroaryBoard / Xib的多語言,以及App內(nèi)切換多語言扰法。最后
說下加上參數(shù) 和 參數(shù)順序的NSLocalizedString
首先讓程序支持多語言
- 創(chuàng)建一個 Localizable 名字的文件轧飞,注意 L 一定要大寫
-
切換到 Project 里衅鹿,添加需要支持的語言,這里只做支持英文 中文
上面步驟完后过咬,會出現(xiàn)兩個文件Localizable.strings(English) Localizable.strings(Simplified)
以 "key" = "value" 的方式添加多語言,如下圖大渤,左邊的是英文,右邊的是中文
代碼用NSLocalizedString(@"key", nil)調(diào)用
如:
self.label.text = NSLocalizedString(@"password", nil);
[self.button setTitle:NSLocalizedString(@"press", nil) forState:UIControlStateNormal];
StoaryBoard/Xib多語言
通常如果StoaryBoard / Xib要支持多語言掸绞,有兩種方法
-
一個是
在Localization里勾選相應(yīng)的Localizable Strings,這樣每個StoaryBoard / Xib 都生成對應(yīng)的幾個Localizable Strings文件泵三,一旦界面有改動,并不會同步到Localizable Strings文件里衔掸,很麻煩烫幕。
第二個辦法
就是IBOutlet每個需要多語言的控件,有很多控件的文字就是寫死的敞映,這樣做也是很麻煩
本文給出兩個方法是讓你在StoaryBoard / Xib界面上直接支持多語言 如 UILabel 控件较曼,為UILable生成一個分類UILabel + XIBLocalizable,同理其他UIButton UITextField UITextVIew等都可以生成對應(yīng)的分類,這里只舉UILable作為例子振愿。
- 第一個辦法利用IBInspectable修飾屬性
@interface UILabel (XIBLocalizabe) @property (nonatomic, copy)IBInspectable NSString *xibLocKey; @end
@implementation UILabel (XIBLocalizabe) - (void)setXibLocKey:(NSString *)xibLocKey{ self.text = xibLocKey.localized; } - (NSString *)xibLocKey{ return nil; } @end
這樣在界面上會多出一個Label屬性捷犹,賦值上多語言對應(yīng)的key值即可
-
第二個辦法 其實已經(jīng)完成了,上面實現(xiàn)了setXibLocKey方法冕末,我們可以在User Defined Runtime Attributes添加xibLocKey這個Key Path
App內(nèi)切換多語言
這里引用了別人實現(xiàn)的 NSBundle+AppLanguageSwitch
簡單講講實現(xiàn)過程
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
object_setClass([NSBundle mainBundle],[ZZBundleEx class]);
NSString *language = [self getCusLanguage];
if (language) {
[self setCusLanguage:language];
}
});
}
這里用了runtime的object_setClass,意思是將[NSBundle mainBundle]的對象指定到 ZZBundleEx 這個類上
@interface ZZBundleEx : NSBundle
@end
@implementation ZZBundleEx
/*ZZBundleEx繼承自NSBundle
并重寫了 - (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName 方法
從NSBundle+AppLanguageSwitch的分類里取出關(guān)聯(lián)屬性 NSBundle值 萍歉,這個值(即xxx.lproj的一個文件)是我們在分類里設(shè)定的對應(yīng)語言的值,所以能達到在APP內(nèi)切換語言的效果
bundle : .../Localizing.app/zh-Hans.lproj 中文
bundle : .../Localizing.app/en.lproj 英文
*/
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
NSBundle *bundle = objc_getAssociatedObject(self, &kBundleKey);
if (bundle) {
return [bundle localizedStringForKey:key value:value table:tableName];
} else {
return [super localizedStringForKey:key value:value table:tableName];
}
}
@end
NSLocalizedString加上參數(shù) 并且根據(jù)語言的不同指定參數(shù)的順序
Locaizable.strings(Chinese (Simplified))
"birth" = "我出生在 %@";
"from" = "我是來自%1$@的%2$@";
Locaizable.strings(English)
"birth" = "I was born in %@";
"from" = "I am %2$@ from %1$@";
ViewController.m
//帶參數(shù)的 NSLocalizedString
self.birthLabel.text = [NSString stringWithFormat:NSLocalizedString(@"birth", nil),@"shenzhen"];
//帶參數(shù) 并且可以指定順序的 NSLocalizedString
self.fromLabel.text = [NSString stringWithFormat:NSLocalizedString(@"from", nil),@"shenzhen",@"hjn"];
看下效果
應(yīng)該很直觀了吧档桃,帶參數(shù)的話本地化文件里直接用%@代替翠桦,代碼里用[NSString stringWithFormat:...]包裹,至于順序就把 %@ 變成 %1$@ 的代表放入第一參數(shù)的值... 以此類推
Demo
最后附上 github Demo