當(dāng)前xcode版本7.2 手機(jī)端 iOS 9.3
? ? ? ?我們的項(xiàng)目已經(jīng)非常龐大了设江,也上線(xiàn)了碴萧,老板突然說(shuō)要加一個(gè)多語(yǔ)言功能嫂侍,在他眼里程序員就是個(gè)魔術(shù)師沾谓,點(diǎn)一個(gè)按鈕然后項(xiàng)目所有的中文字就變成英文的了。聽(tīng)得我都醉了渗稍,于是這兩天我調(diào)研了一下佩迟,寫(xiě)了一個(gè)Demo來(lái)演示如何辦到多語(yǔ)言之間的切換。
Demo地址
? ? ? ?Demo上傳到了github上竿屹,有興趣的童鞋可以下載去看看报强。
實(shí)現(xiàn)方法和原理解釋
? ? ? ?基本上所有的App對(duì)于多語(yǔ)言這塊無(wú)非2種需求,一個(gè)是軟件根據(jù)手機(jī)當(dāng)前操作系統(tǒng)的語(yǔ)言來(lái)顯示對(duì)應(yīng)的語(yǔ)言拱燃。另外一個(gè)種是秉溉,不論當(dāng)前手機(jī)設(shè)置的是什么語(yǔ)言,用戶(hù)可以通過(guò)設(shè)置(點(diǎn)擊按鈕碗誉,就像老板說(shuō)的一樣變魔術(shù))改變當(dāng)前軟件的語(yǔ)言坚嗜。
? ? ? ? 第一種需求的童鞋們可以參考這篇文章,應(yīng)該說(shuō)的很詳細(xì)了诗充,而且也比較簡(jiǎn)單。這里我主要說(shuō)明一下手動(dòng)改變語(yǔ)言設(shè)置的實(shí)現(xiàn)方法诱建。
- xCode創(chuàng)建工程蝴蜓,起名languageChangeDemo,然后創(chuàng)建資源CustomLocalizable.strings
2.添加多語(yǔ)言俺猿,這里我添加了三種語(yǔ)言英文茎匠、簡(jiǎn)體中文、和繁體中文(臺(tái)灣)押袍。
? ? ? ?這樣就變成了第一張圖里面三個(gè).strings 后綴的文件诵冒,相當(dāng)于每個(gè)文件代表了一種語(yǔ)言。這樣基本上就算是配置好了谊惭,接下來(lái)就看怎么用了汽馋。
3.點(diǎn)擊這三個(gè).strings文件,在里面分別寫(xiě)入"showText" = "this is a English Text";
英文的"showText" = "這是一個(gè)簡(jiǎn)體中文";
中文的"showText" = "這是壹個(gè)臺(tái)灣繁體";
繁體的圈盔。
這里實(shí)際上就是說(shuō)豹芯,以后你要給哪個(gè)label顯示文字不要用具體的字了,用這里面的Key來(lái)替代驱敲,然后在不同的語(yǔ)言環(huán)境下铁蹈,會(huì)使用后面的值來(lái)替代。
4.代碼實(shí)現(xiàn)起來(lái)的思路就是你告訴你的工程去文字的時(shí)候從哪個(gè).strings文件中去取众眨。然后調(diào)用
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
來(lái)設(shè)置具體的字符串握牧,通常網(wǎng)上說(shuō)的都會(huì)把這些方法封裝成宏來(lái)實(shí)現(xiàn)容诬。我創(chuàng)建了3個(gè)按鈕,每個(gè)按鈕事件底下寫(xiě)了:
- (IBAction)englishBtn:(UIButton *)sender {
//這句話(huà)告訴項(xiàng)目是從哪個(gè).string文件中取字體沿腰。
_appDelegate.lan = @"en";
//這個(gè)是給上面的label賦值览徒,不管上面語(yǔ)言都賦值那個(gè)Key,但顯示的時(shí)候回事Value
_StrtLabel.text = CustomStr(@"showText");
}
- (IBAction)chineseSimpleBtn:(UIButton *)sender {
_appDelegate.lan =@"zh-Hans";
_StrtLabel.text = CustomStr(@"showText");
}
- (IBAction)chineseTWBtn:(UIButton *)sender {
_appDelegate.lan =@"zh-Hant-TW";
_StrtLabel.text = CustomStr(@"showText");
}
```
       這里的`@"en"``@"zh-Hans"``@"zh-Hant-TW"`你可能會(huì)問(wèn)矫俺,從哪來(lái)的吱殉?實(shí)際上當(dāng)你前面按照我說(shuō)的配置好了以后,你的工程文件夾下面會(huì)有幾個(gè)文件夾厘托。這樣就知道該寫(xiě)什么了吧友雳?
![Snip20160408_15.png](http://upload-images.jianshu.io/upload_images/1538778-cdd500ae5b70b35b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
       我這個(gè)Demo的思路是把這個(gè)字符串存到appDelegate的lan屬性中(我自己創(chuàng)建了一個(gè))。然后剩下一些工作我都在appDelegate里面封裝了一下铅匹,包括宏的定義押赊,目的是讓程序中其他地方設(shè)置字的時(shí)候只用調(diào)用一個(gè)簡(jiǎn)單的宏就行了,例如:`_StrtLabel.text = CustomStr(@"showText");`這樣包斑,下面看一下appDelegate中的一些方法:
AppDelegate.h
```
#import <UIKit/UIKit.h>
//封裝了一個(gè)宏 用來(lái)方便輸入文字--實(shí)際是文字對(duì)應(yīng)的key
#define CustomStr(key) [(AppDelegate *)[[UIApplication sharedApplication] delegate] showText:(key)];
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(strong,nonatomic) NSString *lan; //用來(lái)保存選擇的語(yǔ)言
-(NSString *)showText:(NSString *)key; //用來(lái)替代以往的 NSString 方法
@end
```
AppDelegate.m
```
-(NSString *)showText:(NSString *)key
{
NSString *path = [[NSBundle mainBundle] pathForResource:_lan ofType:@"lproj"];
return [[NSBundle bundleWithPath:path] localizedStringForKey:key value:nil table:@"CustomLocalizable"];
}
```
       AppDelegate.m中`@"lproj"`就是剛才那些存放語(yǔ)言的幾個(gè)文件夾的后綴名`_lan`就是當(dāng)前語(yǔ)言的類(lèi)型了流礁。然后這個(gè)方法就是返回了那些語(yǔ)言包里Key對(duì)應(yīng)的Value值。
       AppDelegate.h中罗丰,我用了一個(gè)宏封裝了一下`-(NSString *)showText:(NSString *)key; `這個(gè)方法的調(diào)用神帅。這樣的好處就是比如好幾個(gè)小伙伴開(kāi)發(fā),他們用直接用這個(gè)宏就行了萌抵,很簡(jiǎn)單找御。
##總結(jié)
       如果你的工程一開(kāi)始就考慮多語(yǔ)言化,那么像我這樣配置好绍填,以后碰到給label賦值霎桅、等等的文字顯示操作都用`CustomStr(key)`這個(gè)宏來(lái)搞定就行了。如果你的工程項(xiàng)目都上線(xiàn)好幾版了讨永,才想起來(lái)這個(gè)問(wèn)題滔驶,那么按照我說(shuō)的辦法配置好,讓你的小伙伴們卿闹,一個(gè)一個(gè)地方改吧揭糕,如果你的項(xiàng)目不是那么大,這個(gè)辦法還是挺好的锻霎。當(dāng)然插佛,如果你的項(xiàng)目像我們一樣,超級(jí)龐大量窘,那么還有一個(gè)更高大上的更改辦法雇寇,前面的這些工作都基本一樣,然后思路就是用正則表達(dá)式查找你工程中所有的中文,然后替換锨侯,然后有一些編譯不過(guò)的地方嫩海,再人工修改,具體的參考[這篇文章](http://www.reibang.com/p/e97584e7ca13
)吧囚痴。目前我的老板還沒(méi)有逼我叁怪,趕緊改。所以這方法我還沒(méi)有試深滚,等哪天實(shí)在沒(méi)辦法了奕谭,我再去試試吧,祝我好運(yùn)痴荐!