前言
語言本地化女蜈,又叫做語言國際化哼蛆。是指根據(jù)用戶操作系統(tǒng)的語言設(shè)置乔宿,自動將應(yīng)用程序的語言設(shè)置為和用戶操作系統(tǒng)語言一致的語言。往往一些應(yīng)用程序需要提供給多個國家的人群使用栏豺,或者一個國家有多種語言,這就要求應(yīng)用程序所展示的文字、圖片等信息鹉梨,能夠讓講不同語言的用戶讀懂、看懂穿稳。進而提出為同一個應(yīng)用程序適配多種語言存皂,也即是國際化。語言國際化之所以又叫做語言本地化逢艘,這是站在每個用戶的角度而言的旦袋,是指能夠讓用戶本地、本土人群能夠看懂的語言信息它改,顧名思義疤孕,語言本地化。其實語言本地化 == 語言國際化央拖!
本文將分如下7個主要章節(jié)一步一步講解如何完全本地化一個App胰柑。
- 配置需要國際化的語言(國際化的準(zhǔn)備工作)
- App名稱本地化
- 代碼中字符串本地化
- 多人開發(fā)情況下的字符串本地化
- 圖片本地化(兩種方式兩種方式)
- 查看/切換本地語言
- storyboard/xib本地化
配置需要國際化的語言
配置需要國際化的語言,這也是國際化之前的準(zhǔn)備工作爬泥,無論我們是國際化App名稱柬讨、代碼中的字符串、圖片袍啡、還是storyboard和xib踩官,都需要進行這一步的準(zhǔn)備工作(一個項目中需要且僅需要配置一次)。
- 選中project->Info->Localizations境输,然后點擊"+"蔗牡,添加需要國際化/本地化的語言颖系,如下圖(默認需要勾選Use Base Internationalization):
-
此處以添加法語為例,如下圖:
彈出如下對話框辩越,直接點擊finish嘁扼,如下圖:
-
同理,添加簡體中文黔攒、繁體中文趁啸、韓語,最終結(jié)果如下圖:
備注:
“zh-Hans”和“zh-Hant”是簡體中文和繁體中文的縮寫督惰。這是標(biāo)準(zhǔn)的縮寫不傅。H可大寫也可小寫。"en"是英語的縮寫赏胚。ko是韓語的縮寫访娶,fr是法語的縮寫。其他語言請百度各國語言縮寫即可查詢觉阅。
(一)應(yīng)用名稱本地化/國際化
應(yīng)用名稱本地化崖疤,是指同一個App的名稱,在不同的語言環(huán)境下(也就是手機設(shè)備的語言設(shè)置)顯示不同的名稱典勇。比如劫哼,微信在簡體中文環(huán)境下App名稱顯示為“微信”,在英語環(huán)境下顯示為“weChat”痴柔。下面就開始進行應(yīng)用名稱本地化沦偎。
- 選中Info.plist,按下鍵盤上的command + N咳蔚,選擇Strings File(iOS->Resource->Strings File)
- 文件名字命名為InfoPlist豪嚎,且必須是這個名字(因每個人電腦設(shè)置差異,此處本人電腦沒有顯示strings后綴名):
- 點擊create后谈火,Xcode左側(cè)導(dǎo)航列表就會出現(xiàn)名為InfoPlist.strings的文件侈询,如下圖:
- 選中InfoPlist.strings,在Xcode的File inspection(Xcode右側(cè)文件檢查器)中點擊Localize糯耍,目的是選擇我們需要本地化的語言扔字,如下圖:
注意:
在點擊Localize之前,一定要保證我們已經(jīng)添加了需要本地化的語言温技,也就是上面配置需要國際化的語言那一步(步驟:project->Info->Localizations革为,然后點擊"+",添加需要國際化/本地化的語言)舵鳞。
- 點擊Localize后震檩,會彈出一個對話框,展開對話框列表,發(fā)現(xiàn)下拉列表所展示的語言正是我們在上面配置的需要國際化的語言抛虏,選擇我們需要本地化的語言博其,然后點擊對話框的Localize按鈕,如下圖:
注意:
如果我們沒有在 PROJECT 中配置需要國際化的語言(project->Info->Localizations迂猴,然后點擊"+")慕淡,上圖下拉列表中將只會出現(xiàn)"Base"和"English"選項,English語言是系統(tǒng)默認的語言沸毁,其他需要國際化的語言(例如中文簡體峰髓、法語)必須通過上面的配置本地化語言那一步手動添加。
- 然后我們發(fā)現(xiàn)Xcode右側(cè)的File inspection變成了下圖的樣式:
- 接下來以清,勾選French儿普、Chinese(zh-Hans)崎逃、Chinese(zh-Hant)掷倔、Korean,如下圖:
- 此時个绍,Xcode左側(cè)的InfoPlist.stirings左側(cè)多了一個箭頭勒葱,點擊箭頭可以展開,如下圖所示:
從上圖可以看出巴柿,InfoPlist.strings文件下包含了English凛虽、French、Chinese(Simplified)广恢、Chinese(Traditional)凯旋、Korean這五種語言的文件。
原理:程序啟動時钉迷,會根據(jù)操作系統(tǒng)設(shè)置的語言至非,自動加載InfoPlist.strings文件下對應(yīng)的語言文件,然后顯示應(yīng)用程序的名字糠聪。
- 接下來荒椭,我們分別用不同的語言給InfoPlist.strings下的文件設(shè)置對應(yīng)的名字。
(1)在InfoPlist.strings(english)中加入如下代碼:
// Localizable App Name是App在英語環(huán)境環(huán)境下顯示的名稱
CFBundleDisplayName = "Localizable App Name";
備注:
CFBundleDisplayName可以使用雙引號舰蟆,也可以不使用雙引號趣惠!
(2)在InfoPlist.strings(French)中加入如下代碼:
CFBundleDisplayName = "Le nom de la localisation de l'App";
(3)在InfoPlist.strings(Chinese(Simplified))中加入如下代碼:
CFBundleDisplayName = "國際化App名稱";
(4)在InfoPlist.strings(Chinese(Traditional))中加入如下代碼:
CFBundleDisplayName = "國際化App名稱";
(5)在InfoPlist.strings(Korean)中加入如下代碼:
CFBundleDisplayName = "??? ? ??";
修改模擬器語言環(huán)境為English。App名稱如下圖:
修改模擬器語言環(huán)境為Chinese(Simplified)身害。App名稱如下圖:
修改模擬器語言環(huán)境為Chinese(Traditional)味悄。App名稱如下圖:
修改模擬器語言環(huán)境為Franch。App名稱如下圖:
修改模擬器語言環(huán)境為Korean塌鸯。App名稱如下圖:
備注:
過去本地化App名稱侍瑟,需要在Info.plist文件中增加一個名為“Application has localized display name”的BOOL類型的Key,并且需要將其值設(shè)置為YES(如下圖)界赔。目的是讓App支持本地化App名稱丢习。但現(xiàn)在可以忽略這一步牵触。
至此,本地化App名稱已經(jīng)演示完畢咐低,其步驟就是:
- 在Project的設(shè)置中通過點擊"+"添加需要本地化的語言揽思。
- 然后在Xcode右側(cè)的File inspection中點擊Localize,選中需要本地化App名稱的語言见擦。
- 最后在每個語言對應(yīng)的文件中以key = value(CFBundleDisplayName = "App名稱";);的形式設(shè)置App的名稱钉汗。
(二)代碼中字符串的本地化
所謂字符串本地化,就是指App內(nèi)的字符串在不同的語言環(huán)境下顯示不同的內(nèi)容鲤屡。比如损痰,"主頁"這個字符串在中文語言環(huán)境下顯示“主頁”,在英語環(huán)境下顯示“home”酒来。下面就開始進行字符串本地化卢未。
其實字符本地化和App名稱本地化過程如出一轍,只是創(chuàng)建的文件名成不一樣(連同后綴一起堰汉,文件名必須是Localizable.strings)辽社,其他步驟完全相同。為了能夠讓大家徹底了解翘鸭,此處還是會把步驟一一貼出來滴铅。
- 和應(yīng)用名稱本地化一樣,首先需要command + N就乓,選擇iOS -> Resource -> Strings File
- 文件名必須命名為Localizable
備注
:因本人電腦取消隱藏文件后綴名汉匙,所以會自動補全.strings后綴名。
- 文件創(chuàng)建成功生蚁,查看Xcode左側(cè)導(dǎo)航列表噩翠,發(fā)現(xiàn)多了一個名為Localizable.strings的文件,如下圖:
- 選中Localizable.strings文件守伸,在Xcode的File inspection中點擊Localize绎秒,目的是選擇我們需要本地化的語言(和本地化App名稱同理),如下圖:
- 依次選擇English->Localize尼摹,如下圖:
- 然后我們發(fā)現(xiàn)Xcode右側(cè)的File inspection變成了下圖的樣式:
- 然后勾選French见芹、Chinese(zh-Hans)、Chinese(zh-Hant)蠢涝、Korean玄呛,如下圖:
- 此時,Xcode左側(cè)的Localizable.stirings左側(cè)多了一個箭頭和二,展開后徘铝,如下圖所示:
- 然后我們只需要在Localizable.strings下對應(yīng)的文件中,分別以Key-Value的形式,為代碼中每一個需要本地化的字符串賦值惕它,如下圖:
- 本地化代碼中的字符串怕午,如下圖:
- 我們只需要使用Foundation框架自帶的NSLocalizedString(key, comment)這個宏根據(jù)Key獲取對應(yīng)的字符串,然后賦值給代碼中的字符串淹魄。
// NSLocalizedString(key, comment) 本質(zhì)
// NSlocalizeString 第一個參數(shù)是內(nèi)容,根據(jù)第一個參數(shù)去對應(yīng)語言的文件中取對應(yīng)的字符串郁惜,第二個參數(shù)將會轉(zhuǎn)化為字符串文件里的注釋,可以傳nil甲锡,也可以傳空字符串@""兆蕉。
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
- 不同語言環(huán)境下運行效果,如下圖:
- 英語環(huán)境下:
- 法語環(huán)境下:
- 簡體中文環(huán)境下:
- 繁體中文環(huán)境下:
- 韓語環(huán)境下:
如此一來缤沦,我們就實現(xiàn)了代碼中字符串的本地化虎韵。
技巧
- 其實,我們不需要給Localizable.strings(English)文件添加Key-Value缸废。原因如下:系統(tǒng)根據(jù)某個key去獲取對應(yīng)的字符串時包蓝,如果沒有找到,那么就會以key作為value返回呆奕。所以如果我們在Localizable.strings(English)文件中沒有添加 click = "hit";那么在english環(huán)境下btn最終顯示的title會是click.
- 切換語言無需在模擬器中設(shè)置养晋,只需要在Xcode中進行如下設(shè)置: Edit->Scheme->Run->Arguments Passed On Launch ->-AppleLanguages (語言代碼)衬吆。例如梁钾,我們模擬器此時雖然是韓語,如果通過上述步驟設(shè)置為zh-Hans逊抡,那么語言環(huán)境將會變?yōu)闈h語姆泻,如下圖:
- 運行效果:
- 如此一來,切換語言變得更加簡單冒嫡,無需在模擬器的設(shè)置中進行繁瑣的語言切換拇勃。
(三)多人開發(fā)情況下的字符串本地化
項目開發(fā)中,獨立開發(fā)的還是少數(shù)孝凌。經(jīng)常會有多人開發(fā)的情況方咆,這種情況,如果多人同時操作本地化文件蟀架,極有可能會存在沖突瓣赂。另一方面,我們又不希望自己的本地化文件受到對方的污染片拍,也就是說煌集,我們不希望對方操作我們的本地化文件。但是上面介紹的代碼中字符串的本地化是使用的是默認的文件名"Localizable",因為啟動程序時捌省,系統(tǒng)將根據(jù)語言加載相應(yīng)的文件得到其對應(yīng)的字符串文件苫纤,這個字符串可以通過系統(tǒng)將NSLocalizedString中的宏生成名為“Localizable.strings”的文件。那么如何讓系統(tǒng)加載我們自己命名的本地化文件而非系統(tǒng)默認的Localizable.strings呢?這就是 NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)的用處卷拘。
也就是說喊废,如果你的strings文件名字不是Localizable而是自定義的話,如VVS.strings栗弟,那么你就得使用NSLocalizedStringFromTable這個宏來讀取本地化字符串操禀。
// key:系統(tǒng)根據(jù)key取字符串
// tbl:自定義strings文件的名字
// comment:可以不傳
NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *btn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *title = NSLocalizedStringFromTable(@"click", @"VVS", nil);
[self.btn setTitle:title forState:UIControlStateNormal];
}
@end
- 運行效果,如下圖:
如此一來横腿,我們就可以掙脫別人的strings文件和系統(tǒng)默認的Localizable.strings文件颓屑,自己另起爐灶。
(四)圖片本地化
本地化圖片耿焊,有兩種方式揪惦,第一種方式和本地化代碼中的字符串一樣,通過NSLocalizedString(key,comment)來獲取相應(yīng)的字符串罗侯,然后根據(jù)這個字符串再獲取圖片器腋。
方式一
NSString *imageName = NSLocalizedString(@"icon", nil);
UIImage *image = [UIImage imageNamed:imageName];
self.imageView.image = image;
方式二
首先需要添加需要本地化的語言,具體步驟參考第一章配置需要國際化的語言钩杰。因為我演示的demo中在本地化App名稱時已經(jīng)添加了需要國際化的語言纫塌。所以不需要再設(shè)置。
- 將圖片拖入工程中讲弄,例如“icon.png”措左,然后選中icon.png,展開Xcode右側(cè)的file Inspection避除,點擊Localize怎披,如下圖:
- 然后,右擊icon.png->show in Finder瓶摆,我們發(fā)現(xiàn)在en.Iproj文件中多了一個名為icon.png的圖片凉逛,如下圖:
- 當(dāng)然,zh-Hans.Iproj文件夾下并沒有圖片群井,如下圖:
- 我們只需給zh-Hans.Iproj添加一個名字也為icon.png的圖片状飞。如下圖:
- 然后把zh-Hans.Iproj中的icon.png拖到Xcode中,如下圖:
- 然后發(fā)現(xiàn)书斜,icon.png左邊出現(xiàn)了一個可以展開的三角形诬辈。如下圖:
- 展開后發(fā)現(xiàn)里面包含兩張圖片,如下圖:
然后控制器中添加如下代碼:
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *imageName = NSLocalizedString(@"icon", nil);
UIImage *image = [UIImage imageNamed:imageName];
self.imageView.image = image;
}
@end
- english環(huán)境下運行效果如下:
- 中文環(huán)境改下運行效果如下:
- 其他語言環(huán)境菩佑,例如法語自晰、中文繁體、韓語稍坯,操作步驟完全和上面相同酬荞。都是在對應(yīng)的.Iproj文件夾下添加同名的圖片搓劫,然后把圖片拖放到Xcode中,不再贅述混巧。
(五)查看/切換本地語言
原理:應(yīng)用啟動時枪向,首先會讀取NSUserDefaults中的key為AppleLanguages對應(yīng)的value,該value是一個String數(shù)組咧党,也就是說秘蛔,我們訪問這個名為AppleLanguages的key可以返回一個string數(shù)組,該數(shù)組存儲著APP支持的語言列表傍衡,數(shù)組的第一項為APP當(dāng)前默認的語言深员。
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
NSString *currentLanguage = languages.firstObject;
NSLog(@"模擬器當(dāng)前語言:%@",currentLanguage);
}
@end
-控制臺打印結(jié)果:
同理,既然我們可以通過AppleLanguages這個key從NSUserDefaults中取出語言數(shù)組蛙埂,那么我們也可以給AppleLanguages這個key賦值來達到切換本地語言的效果倦畅,從此以后,我們就無需頻繁的去模擬器的設(shè)置->通用->語言與地區(qū) 中切換語言绣的。
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 切換語言前
NSArray *langArr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
NSString *language1 = langArr1.firstObject;
NSLog(@"模擬器語言切換之前:%@",language1);
// 切換語言
NSArray *lans = @[@"en"];
[[NSUserDefaults standardUserDefaults] setObject:lans forKey:@"AppleLanguages"];
// 切換語言后
NSArray *langArr2 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
NSString *language2 = langArr2.firstObject;
NSLog(@"模擬器語言切換之后:%@",language2);
}
@end
- 回想一下叠赐,我在上面的技巧一節(jié)中提過:切換語言無需在模擬器中設(shè)置,只需要在Xcode中進行如下設(shè)置: Edit->Scheme->Run->Arguments Passed On Launch ->-AppleLanguages (語言代碼)屡江。其實本質(zhì)上就是給NSUserDefaults中名為AppleLanguages的key賦值芭概。
未完待續(xù)...
文/VV木公子(簡書作者)
PS:如非特別說明,所有文章均為原創(chuàng)作品惩嘉,著作權(quán)歸作者所有罢洲,轉(zhuǎn)載轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),并注明出處宏怔,所有打賞均歸本人所有奏路!
如果您是iOS開發(fā)者,或者對本篇文章感興趣臊诊,請關(guān)注本人,后續(xù)會更新更多相關(guān)文章斜脂!敬請期待抓艳!