當前xcode版本7.2 手機端 iOS 9.3
? ? ? ?我們的項目已經非常龐大了,也上線了,老板突然說要加一個多語言功能,在他眼里程序員就是個魔術師,點一個按鈕然后項目所有的中文字就變成英文的了。聽得我都醉了,于是這兩天我調研了一下,寫了一個Demo來演示如何辦到多語言之間的切換。
Demo地址
? ? ? ?Demo上傳到了github上,有興趣的童鞋可以下載去看看。
實現方法和原理解釋
? ? ? ?基本上所有的App對于多語言這塊無非2種需求,一個是軟件根據手機當前操作系統的語言來顯示對應的語言。另外一個種是,不論當前手機設置的是什么語言,用戶可以通過設置(點擊按鈕,就像老板說的一樣變魔術)改變當前軟件的語言。
? ? ? ? 第一種需求的童鞋們可以參考這篇文章,應該說的很詳細了,而且也比較簡單。這里我主要說明一下手動改變語言設置的實現方法。
- xCode創建工程,起名languageChangeDemo,然后創建資源CustomLocalizable.strings
1.創建.strings資源文件
2.添加多語言,這里我添加了三種語言英文、簡體中文、和繁體中文(臺灣)。
2.添加語言
3.默認就選個英文先添加上
4.添加語言
點擊.strings文件把語言勾選上
? ? ? ?這樣就變成了第一張圖里面三個.strings 后綴的文件,相當于每個文件代表了一種語言。這樣基本上就算是配置好了,接下來就看怎么用了。
3.點擊這三個.strings文件,在里面分別寫入"showText" = "this is a English Text";
英文的"showText" = "這是一個簡體中文";
中文的"showText" = "這是壹個臺灣繁體";
繁體的。
鍵值
這里實際上就是說,以后你要給哪個label顯示文字不要用具體的字了,用這里面的Key來替代,然后在不同的語言環境下,會使用后面的值來替代。
4.代碼實現起來的思路就是你告訴你的工程去文字的時候從哪個.strings文件中去取。然后調用
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
來設置具體的字符串,通常網上說的都會把這些方法封裝成宏來實現。xib視圖
我創建了3個按鈕,每個按鈕事件底下寫了:
- (IBAction)englishBtn:(UIButton *)sender {
//這句話告訴項目是從哪個.string文件中取字體。
_appDelegate.lan = @"en";
//這個是給上面的label賦值,不管上面語言都賦值那個Key,但顯示的時候回事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"`你可能會問,從哪來的?實際上當你前面按照我說的配置好了以后,你的工程文件夾下面會有幾個文件夾。這樣就知道該寫什么了吧?

       我這個Demo的思路是把這個字符串存到appDelegate的lan屬性中(我自己創建了一個)。然后剩下一些工作我都在appDelegate里面封裝了一下,包括宏的定義,目的是讓程序中其他地方設置字的時候只用調用一個簡單的宏就行了,例如:`_StrtLabel.text = CustomStr(@"showText");`這樣,下面看一下appDelegate中的一些方法:
AppDelegate.h
```
#import <UIKit/UIKit.h>
//封裝了一個宏 用來方便輸入文字--實際是文字對應的key
#define CustomStr(key) [(AppDelegate *)[[UIApplication sharedApplication] delegate] showText:(key)];
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(strong,nonatomic) NSString *lan; //用來保存選擇的語言
-(NSString *)showText:(NSString *)key; //用來替代以往的 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"`就是剛才那些存放語言的幾個文件夾的后綴名`_lan`就是當前語言的類型了。然后這個方法就是返回了那些語言包里Key對應的Value值。
       AppDelegate.h中,我用了一個宏封裝了一下`-(NSString *)showText:(NSString *)key; `這個方法的調用。這樣的好處就是比如好幾個小伙伴開發,他們用直接用這個宏就行了,很簡單。
##總結
       如果你的工程一開始就考慮多語言化,那么像我這樣配置好,以后碰到給label賦值、等等的文字顯示操作都用`CustomStr(key)`這個宏來搞定就行了。如果你的工程項目都上線好幾版了,才想起來這個問題,那么按照我說的辦法配置好,讓你的小伙伴們,一個一個地方改吧,如果你的項目不是那么大,這個辦法還是挺好的。當然,如果你的項目像我們一樣,超級龐大,那么還有一個更高大上的更改辦法,前面的這些工作都基本一樣,然后思路就是用正則表達式查找你工程中所有的中文,然后替換,然后有一些編譯不過的地方,再人工修改,具體的參考[這篇文章](http://www.lxweimin.com/p/e97584e7ca13
)吧。目前我的老板還沒有逼我,趕緊改。所以這方法我還沒有試,等哪天實在沒辦法了,我再去試試吧,祝我好運!