【轉】3分鐘實現(xiàn)iOS語言本地化/國際化(圖文詳解)

前言

語言本地化,又叫做語言國際化沫勿。是指根據(jù)用戶操作系統(tǒng)的語言設置挨约,自動將應用程序的語言設置為和用戶操作系統(tǒng)語言一致的語言。往往一些應用程序需要提供給多個國家的人群使用产雹,或者一個國家有多種語言诫惭,這就要求應用程序所展示的文字、圖片等信息蔓挖,能夠讓講不同語言的用戶讀懂夕土、看懂。進而提出為同一個應用程序適配多種語言瘟判,也即是國際化怨绣。語言國際化之所以又叫做語言本地化,這是站在每個用戶的角度而言的拷获,是指能夠讓用戶本地篮撑、本土人群能夠看懂的語言信息,顧名思義匆瓜,語言本地化咽扇。其實語言本地化 == 語言國際化!

本文將分如下7個主要章節(jié)一步一步講解如何完全本地化一個App陕壹。

配置需要國際化的語言(國際化的準備工作)

App名稱本地化

代碼中字符串本地化

多人開發(fā)情況下的字符串本地化

圖片本地化(兩種方式兩種方式)

查看/切換本地語言

storyboard/xib本地化

配置需要國際化的語言

配置需要國際化的語言质欲,這也是國際化之前的準備工作,無論我們是國際化App名稱糠馆、代碼中的字符串嘶伟、圖片、還是storyboard和xib又碌,都需要進行這一步的準備工作(一個項目中需要且僅需要配置一次)九昧。

選中project->Info->Localizations绊袋,然后點擊"+",添加需要國際化/本地化的語言铸鹰,如下圖(默認需要勾選Use Base Internationalization):

Snip20160616_15.png

此處以添加法語為例癌别,如下圖:

Snip20160616_18.png

彈出如下對話框,直接點擊finish蹋笼,如下圖:

Snip20160616_21.png

同理展姐,添加簡體中文、繁體中文剖毯、韓語圾笨,最終結果如下圖:

Snip20160616_22.png

備注:“zh-Hans”和“zh-Hant”是簡體中文和繁體中文的縮寫。這是標準的縮寫逊谋。H可大寫也可小寫擂达。"en"是英語的縮寫。ko是韓語的縮寫胶滋,fr是法語的縮寫板鬓。其他語言請百度各國語言縮寫即可查詢。

(一)應用名稱本地化/國際化

應用名稱本地化究恤,是指同一個App的名稱俭令,在不同的語言環(huán)境下(也就是手機設備的語言設置)顯示不同的名稱。比如丁溅,微信在簡體中文環(huán)境下App名稱顯示為“微信”唤蔗,在英語環(huán)境下顯示為“weChat”探遵。下面就開始進行應用名稱本地化窟赏。

選中Info.plist,按下鍵盤上的command + N箱季,選擇Strings File(iOS->Resource->Strings File)

Snip20160616_10.png

文件名字命名為InfoPlist涯穷,且必須是這個名字(因每個人電腦設置差異,此處本人電腦沒有顯示strings后綴名):

Snip20160616_11.png

點擊create后藏雏,Xcode左側導航列表就會出現(xiàn)名為InfoPlist.strings的文件,如下圖:

Snip20160616_13.png

選中InfoPlist.strings,在Xcode的File inspection(Xcode右側文件檢查器)中點擊Localize蹲嚣,目的是選擇我們需要本地化的語言车摄,如下圖:

注意:在點擊Localize之前,一定要保證我們已經(jīng)添加了需要本地化的語言奏寨,也就是上面配置需要國際化的語言那一步(步驟:project->Info->Localizations起意,然后點擊"+",添加需要國際化/本地化的語言)病瞳。

Snip20160616_14.png

點擊Localize后揽咕,會彈出一個對話框悲酷,展開對話框列表,發(fā)現(xiàn)下拉列表所展示的語言正是我們在上面配置的需要國際化的語言亲善,選擇我們需要本地化的語言设易,然后點擊對話框的Localize按鈕,如下圖:

Snip20160617_10.png

Snip20160617_12.png

注意:如果我們沒有在 PROJECT 中配置需要國際化的語言(project->Info->Localizations蛹头,然后點擊"+")顿肺,上圖下拉列表中將只會出現(xiàn)"Base"和"English"選項,English語言是系統(tǒng)默認的語言掘而,其他需要國際化的語言(例如中文簡體挟冠、法語)必須通過上面的配置本地化語言那一步手動添加。

然后我們發(fā)現(xiàn)Xcode右側的File inspection變成了下圖的樣式:

Snip20160617_13.png

接下來袍睡,勾選French知染、Chinese(zh-Hans)、Chinese(zh-Hant)斑胜、Korean控淡,如下圖:

Snip20160617_14.png

此時,Xcode左側的InfoPlist.stirings左側多了一個箭頭止潘,點擊箭頭可以展開掺炭,如下圖所示:

Snip20160617_15.png

從上圖可以看出,InfoPlist.strings文件下包含了English凭戴、French涧狮、Chinese(Simplified)、Chinese(Traditional)么夫、Korean這五種語言的文件者冤。

原理:程序啟動時,會根據(jù)操作系統(tǒng)設置的語言档痪,自動加載InfoPlist.strings文件下對應的語言文件涉枫,然后顯示應用程序的名字。

接下來腐螟,我們分別用不同的語言給InfoPlist.strings下的文件設置對應的名字愿汰。

(1)在InfoPlist.strings(english)中加入如下代碼:

// Localizable App Name是App在英語環(huán)境環(huán)境下顯示的名稱

CFBundleDisplayName = "Localizable App Name";

備注:CFBundleDisplayName可以使用雙引號,也可以不使用雙引號乐纸!

Snip20160617_21.png

(2)在InfoPlist.strings(French)中加入如下代碼:

CFBundleDisplayName = "Le nom de la localisation de l'App";

Snip20160617_27.png

(3)在InfoPlist.strings(Chinese(Simplified))中加入如下代碼:

CFBundleDisplayName = "國際化App名稱";

Snip20160617_32.png

(4)在InfoPlist.strings(Chinese(Traditional))中加入如下代碼:

CFBundleDisplayName = "國際化App名稱";

Snip20160617_30.png

(5)在InfoPlist.strings(Korean)中加入如下代碼:

CFBundleDisplayName = "??? ? ??";

Snip20160617_31.png

修改模擬器語言環(huán)境為English衬廷。App名稱如下圖:

Snip20160617_33.png

修改模擬器語言環(huán)境為Chinese(Simplified)。App名稱如下圖:

Snip20160618_4.png

修改模擬器語言環(huán)境為Chinese(Traditional)汽绢。App名稱如下圖:

Snip20160618_5.png

修改模擬器語言環(huán)境為Franch吗跋。App名稱如下圖:

Snip20160618_6.png

修改模擬器語言環(huán)境為Korean。App名稱如下圖:

Snip20160618_7.png

備注:過去本地化App名稱庶喜,需要在Info.plist文件中增加一個名為“Application has localized display name”的BOOL類型的Key小腊,并且需要將其值設置為YES(如下圖)救鲤。目的是讓App支持本地化App名稱。但現(xiàn)在可以忽略這一步秩冈。

Snip20160618_8.png

至此本缠,本地化App名稱已經(jīng)演示完畢,其步驟就是:

在Project的設置中通過點擊"+"添加需要本地化的語言入问。

然后在Xcode右側的File inspection中點擊Localize丹锹,選中需要本地化App名稱的語言。

最后在每個語言對應的文件中以key = value(CFBundleDisplayName = "App名稱";);的形式設置App的名稱芬失。

(二)代碼中字符串的本地化

所謂字符串本地化楣黍,就是指App內(nèi)的字符串在不同的語言環(huán)境下顯示不同的內(nèi)容。比如棱烂,"主頁"這個字符串在中文語言環(huán)境下顯示“主頁”租漂,在英語環(huán)境下顯示“home”。下面就開始進行字符串本地化颊糜。

其實字符本地化和App名稱本地化過程如出一轍哩治,只是創(chuàng)建的文件名成不一樣(連同后綴一起,文件名必須是Localizable.strings)衬鱼,其他步驟完全相同业筏。為了能夠讓大家徹底了解,此處還是會把步驟一一貼出來鸟赫。

和應用名稱本地化一樣蒜胖,首先需要command + N,選擇iOS -> Resource -> Strings File

文件名必須命名為Localizable

備注:因本人電腦取消隱藏文件后綴名抛蚤,所以會自動補全.strings后綴名台谢。

Snip20160619_8.png

文件創(chuàng)建成功,查看Xcode左側導航列表霉颠,發(fā)現(xiàn)多了一個名為Localizable.strings的文件对碌,如下圖:

Snip20160619_4.png

選中Localizable.strings文件荆虱,在Xcode的File inspection中點擊Localize蒿偎,目的是選擇我們需要本地化的語言(和本地化App名稱同理),如下圖:

依次選擇English->Localize怀读,如下圖:

然后我們發(fā)現(xiàn)Xcode右側的File inspection變成了下圖的樣式:

然后勾選French诉位、Chinese(zh-Hans)、Chinese(zh-Hant)菜枷、Korean苍糠,如下圖:

此時啤誊,Xcode左側的Localizable.stirings左側多了一個箭頭,展開后尼斧,如下圖所示:

Snip20160619_6.png

然后我們只需要在Localizable.strings下對應的文件中烛恤,分別以Key-Value的形式余耽,為代碼中每一個需要本地化的字符串賦值缚柏,如下圖:

Snip20160619_9.png

Snip20160619_10.png

Snip20160619_12.png

Snip20160619_13.png

Snip20160619_14.png

本地化代碼中的字符串,如下圖:

Snip20160619_15.png

我們只需要使用Foundation框架自帶的NSLocalizedString(key, comment)這個宏根據(jù)Key獲取對應的字符串碟贾,然后賦值給代碼中的字符串币喧。

// NSLocalizedString(key, comment) 本質

// NSlocalizeString 第一個參數(shù)是內(nèi)容,根據(jù)第一個參數(shù)去對應語言的文件中取對應的字符串,第二個參數(shù)將會轉化為字符串文件里的注釋袱耽,可以傳nil杀餐,也可以傳空字符串@""。

#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

不同語言環(huán)境下運行效果朱巨,如下圖:

英語環(huán)境下:

Snip20160619_17.png

法語環(huán)境下:

Snip20160619_18.png

簡體中文環(huán)境下:

Snip20160619_19.png

繁體中文環(huán)境下:

Snip20160619_20.png

韓語環(huán)境下:

Snip20160619_23.png

如此一來史翘,我們就實現(xiàn)了代碼中字符串的本地化。

技巧

其實,我們不需要給Localizable.strings(English)文件添加Key-Value琼讽。原因如下:系統(tǒng)根據(jù)某個key去獲取對應的字符串時必峰,如果沒有找到,那么就會以key作為value返回钻蹬。所以如果我們在Localizable.strings(English)文件中沒有添加 click = "hit";那么在english環(huán)境下btn最終顯示的title會是click.

切換語言無需在模擬器中設置自点,只需要在Xcode中進行如下設置: Edit->Scheme->Run->Arguments Passed On Launch ->-AppleLanguages (語言代碼)。例如脉让,我們模擬器此時雖然是韓語桂敛,如果通過上述步驟設置為zh-Hans,那么語言環(huán)境將會變?yōu)闈h語溅潜,如下圖:

Snip20160619_26.png

Snip20160619_28.png

運行效果:

Snip20160619_29.png

如此一來术唬,切換語言變得更加簡單,無需在模擬器的設置中進行繁瑣的語言切換滚澜。

(三)多人開發(fā)情況下的字符串本地化

項目開發(fā)中粗仓,獨立開發(fā)的還是少數(shù)。經(jīng)常會有多人開發(fā)的情況设捐,這種情況借浊,如果多人同時操作本地化文件,極有可能會存在沖突萝招。另一方面蚂斤,我們又不希望自己的本地化文件受到對方的污染,也就是說槐沼,我們不希望對方操作我們的本地化文件曙蒸。但是上面介紹的代碼中字符串的本地化是使用的是默認的文件名"Localizable",因為啟動程序時,系統(tǒng)將根據(jù)語言加載相應的文件得到其對應的字符串文件岗钩,這個字符串可以通過系統(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#>)

Snip20160619_32.png

#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

運行效果,如下圖:

Snip20160619_33.png

如此一來凶朗,我們就可以掙脫別人的strings文件和系統(tǒng)默認的Localizable.strings文件瓷胧,自己另起爐灶显拳。

(四)圖片本地化

本地化圖片棚愤,有兩種方式,第一種方式和本地化代碼中的字符串一樣,通過NSLocalizedString(key,comment)來獲取相應的字符串宛畦,然后根據(jù)這個字符串再獲取圖片瘸洛。

方式一

NSString *imageName = NSLocalizedString(@"icon", nil);

UIImage *image = [UIImage imageNamed:imageName];

self.imageView.image = image;

方式二

首先需要添加需要本地化的語言,具體步驟參考第一章配置需要國際化的語言次和。因為我演示的demo中在本地化App名稱時已經(jīng)添加了需要國際化的語言反肋。所以不需要再設置。

將圖片拖入工程中踏施,例如“icon.png”石蔗,然后選中icon.png,展開Xcode右側的file Inspection畅形,點擊Localize养距,如下圖:

Snip20160619_36.png

然后,右擊icon.png->show in Finder日熬,我們發(fā)現(xiàn)在en.Iproj文件中多了一個名為icon.png的圖片棍厌,如下圖:

Snip20160619_38.png

當然,zh-Hans.Iproj文件夾下并沒有圖片竖席,如下圖:

Snip20160619_39.png

我們只需給zh-Hans.Iproj添加一個名字也為icon.png的圖片耘纱。如下圖:

Snip20160619_40.png

然后把zh-Hans.Iproj中的icon.png拖到Xcode中,如下圖:

Snip20160619_43.png

然后發(fā)現(xiàn)毕荐,icon.png左邊出現(xiàn)了一個可以展開的三角形束析。如下圖:

Snip20160619_44.png

展開后發(fā)現(xiàn)里面包含兩張圖片,如下圖:

Snip20160619_45.png

然后控制器中添加如下代碼:

#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)境下運行效果如下:

Snip20160620_46.png

中文環(huán)境改下運行效果如下:

Snip20160620_47.png

其他語言環(huán)境憎亚,例如法語畸陡、中文繁體、韓語虽填,操作步驟完全和上面相同丁恭。都是在對應的.Iproj文件夾下添加同名的圖片,然后把圖片拖放到Xcode中斋日,不再贅述牲览。

(五)查看/切換本地語言

原理:應用啟動時,首先會讀取NSUserDefaults中的key為AppleLanguages對應的value恶守,該value是一個String數(shù)組第献,也就是說,我們訪問這個名為AppleLanguages的key可以返回一個string數(shù)組兔港,該數(shù)組存儲著APP支持的語言列表庸毫,數(shù)組的第一項為APP當前默認的語言。

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];

NSString *currentLanguage = languages.firstObject;

NSLog(@"模擬器當前語言:%@",currentLanguage);

}

@end

-控制臺打印結果:

Snip20160620_1.png

同理衫樊,既然我們可以通過AppleLanguages這個key從NSUserDefaults中取出語言數(shù)組飒赃,那么我們也可以給AppleLanguages這個key賦值來達到切換本地語言的效果利花,從此以后,我們就無需頻繁的去模擬器的設置->通用->語言與地區(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

Snip20160620_2.png

回想一下炒事,我在上面的技巧一節(jié)中提過:切換語言無需在模擬器中設置,只需要在Xcode中進行如下設置: Edit->Scheme->Run->Arguments Passed On Launch ->-AppleLanguages (語言代碼)蔫慧。其實本質上就是給NSUserDefaults中名為AppleLanguages的key賦值挠乳。

作者:VV木公子

鏈接:http://www.reibang.com/p/88c1b65e3ddb

來源:簡書

著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權姑躲,非商業(yè)轉載請注明出處睡扬。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市黍析,隨后出現(xiàn)的幾起案子威蕉,更是在濱河造成了極大的恐慌,老刑警劉巖橄仍,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件韧涨,死亡現(xiàn)場離奇詭異,居然都是意外死亡侮繁,警方通過查閱死者的電腦和手機虑粥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪哩,“玉大人娩贷,你說我怎么就攤上這事∷希” “怎么了彬祖?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長品抽。 經(jīng)常有香客問我储笑,道長,這世上最難降的妖魔是什么圆恤? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任突倍,我火速辦了婚禮,結果婚禮上盆昙,老公的妹妹穿的比我還像新娘羽历。我一直安慰自己,他們只是感情好淡喜,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布秕磷。 她就那樣靜靜地躺著,像睡著了一般炼团。 火紅的嫁衣襯著肌膚如雪澎嚣。 梳的紋絲不亂的頭發(fā)上疏尿,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音币叹,去河邊找鬼润歉。 笑死模狭,一個胖子當著我的面吹牛颈抚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嚼鹉,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼贩汉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锚赤?” 一聲冷哼從身側響起匹舞,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎线脚,沒想到半個月后赐稽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡浑侥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年姊舵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寓落。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡括丁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伶选,到底是詐尸還是另有隱情史飞,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布仰税,位于F島的核電站构资,受9級特大地震影響,放射性物質發(fā)生泄漏陨簇。R本人自食惡果不足惜蚯窥,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一欧瘪、第九天 我趴在偏房一處隱蔽的房頂上張望廷没。 院中可真熱鬧疮鲫,春花似錦粤剧、人聲如沸槽唾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琅豆。三九已至榔幸,卻和暖如春允乐,著一層夾襖步出監(jiān)牢的瞬間矮嫉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工牍疏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蠢笋,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓鳞陨,卻偏偏與公主長得像昨寞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子厦滤,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容