iOS 多語(yǔ)言版本的開(kāi)發(fā)(二)

iOS 多語(yǔ)言版本的開(kāi)發(fā)(二)

題記

iOS 多語(yǔ)言版本的開(kāi)發(fā)(一) 中我們完成了讓?xiě)?yīng)用跟隨系統(tǒng)語(yǔ)言進(jìn)行切換,而用戶自己卻不能切換的功能,也基本上算是實(shí)現(xiàn)了多語(yǔ)言版本;可是,對(duì)于某些應(yīng)用來(lái)說(shuō),實(shí)現(xiàn)跟隨系統(tǒng)語(yǔ)言切換的同時(shí), 也想要實(shí)現(xiàn)讓用戶自己選擇應(yīng)用語(yǔ)言版本的功能;針對(duì)這種情況,利用這篇文章來(lái)寫(xiě)寫(xiě)如何讓用戶自己切換應(yīng)用語(yǔ)言版本;

語(yǔ)言文件存在的形式

想要實(shí)現(xiàn)用戶自己手動(dòng)切換語(yǔ)言版本,就先要了解語(yǔ)言文件在資源文件中存在的形式;

localized09.jpg

如圖中,不管是英語(yǔ)(en.lproj)、簡(jiǎn)體(zh-Hans.lproj)、還是繁體(zh-Hant.lproj)都是以.lproj的文件夾形式存在, 所以當(dāng)我們要切換語(yǔ)言的時(shí)候,其實(shí)也就是做到去取這些.lproj文件夾中的ASLocalized.strings文件;

到這里,原理應(yīng)該懂了,接下來(lái)就是動(dòng)手實(shí)現(xiàn)了;

根據(jù)語(yǔ)言獲取ASLocalized.strings

這時(shí)候,需要根據(jù)不同的語(yǔ)言.lproj獲取到對(duì)應(yīng)的ASLocalized.strings語(yǔ)言文件, 從而讓頁(yè)面顯示對(duì)應(yīng)的語(yǔ)言內(nèi)容;
這里暫且先根據(jù)English獲取英語(yǔ)的語(yǔ)言文件,English 的.lproj存在的形式是en.lproj

NSString *path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
NSString *showValue = [[NSBundle bundleWithPath:path] localizedStringForKey:@"showTxt" value:nil table:@"ASLocalized"];
NSLog(@"result: %@", showValue);

輸出結(jié)果:result: this is test text

以上代碼,只是以English 為語(yǔ)言文件,是寫(xiě)死的,如果想要讓用戶自己手動(dòng)改變,只需要替換掉[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"]中的en為其他的語(yǔ)言標(biāo)識(shí)就好了; 既然是用戶手動(dòng)切換,那就需要寫(xiě)代碼去實(shí)現(xiàn)了;

到這里,有一個(gè)問(wèn)題,如何讓用戶選擇后一個(gè)語(yǔ)言后,即使程序退出后,下次進(jìn)入依然保留呢, 既然需要保存數(shù)據(jù),就要涉及到本地存儲(chǔ)了,對(duì)于少量的保存我們可以使用NSUserDefaults 來(lái)操作,簡(jiǎn)單方便快捷;至于其他的存儲(chǔ)方式四大基本對(duì)象的write方法,歸檔,sqllite,CoreData 需要的同學(xué),可以自己去腦補(bǔ),這里我不多介紹了;

使用NSUserDefaults 記錄選擇的語(yǔ)言

這里我簡(jiǎn)單寫(xiě)了個(gè)界面,作為輔助講解


localized10.jpg
- (IBAction)changeLanguage:(UIButton *)sender {
    
    switch (sender.tag) {
        case 101: { //簡(jiǎn)體
            [[NSUserDefaults standardUserDefaults] setObject:@"zh-Hans" forKey:appLanguage];
        }
            break;
        case 102: { //繁體
            [[NSUserDefaults standardUserDefaults] setObject:@"zh-Hant" forKey:appLanguage];
        }
            break;
        case 103: { //English
            [[NSUserDefaults standardUserDefaults] setObject:@"en" forKey:appLanguage];
        }
            break;
        default:
            break;
    }
}

以上方法,是圖中三種語(yǔ)言的點(diǎn)擊事件,分別將對(duì)應(yīng)的語(yǔ)言標(biāo)識(shí),記錄到NSUserDefaults 對(duì)應(yīng)的 appLanguage key 中

既然重新選擇了語(yǔ)言,就需要重新加載控件的內(nèi)容,因?yàn)槭荄emo??,這里直接將給控件賦值寫(xiě)成一個(gè)方法,如下:

- (void)showLbl {
    NSString *lanType =[NSString stringWithFormat:@"%@", [[NSUserDefaults standardUserDefaults] objectForKey:@"appLanguage"]];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:lanType ofType:@"lproj"];
    
    NSString *showValue = [[NSBundle bundleWithPath:path] localizedStringForKey:@"showTxt" value:nil table:@"ASLocalized"];
    NSLog(@"result: %@", showValue);
    self.lblShowTxt.text = showValue;
}

可將此方法在點(diǎn)擊事件中調(diào)用下,即可;

Demo效果圖:


localized11.gif

首次進(jìn)入應(yīng)用的考慮

到這里,還沒(méi)有完,這時(shí)我們需要考慮下,用戶第一次進(jìn)來(lái)時(shí),該顯示什么樣的語(yǔ)言,是跟隨系統(tǒng),還是我們給一種默認(rèn)的語(yǔ)言;

1、給一種默認(rèn)語(yǔ)言

這種處理很簡(jiǎn)單,只需要在didFinishLaunchingWithOptions 方法中,進(jìn)行判斷本地是否記錄了語(yǔ)言標(biāo)識(shí),如果沒(méi)有給一種默認(rèn)即可,代碼如下:

if (![[NSUserDefaults standardUserDefaults] objectForKey:appLanguage]) { 
     [[NSUserDefaults standardUserDefaults] setObject:@"zh-Hans"    forKey:appLanguage];
}

2、跟隨系統(tǒng)語(yǔ)言

這種處理相對(duì)來(lái)說(shuō),比較復(fù)雜寫(xiě),首頁(yè)需要獲取系統(tǒng)的首選語(yǔ)言順序,然后取第一個(gè)首選語(yǔ)言,其次,還要判斷你要做的語(yǔ)言版本,首選語(yǔ)言組中存在與否;
獲取首選語(yǔ)言:NSArray *languages = [NSLocale preferredLanguages];
獲取第一個(gè)首選語(yǔ)言: NSString *language = [languages objectAtIndex:0];

處理過(guò)程如下:

if (![[NSUserDefaults standardUserDefaults] objectForKey:appLanguage]) {
        NSArray  *languages = [NSLocale preferredLanguages];
        NSString *language = [languages objectAtIndex:0];
        if ([language hasPrefix:@"zh-Hans"]) {
            [[NSUserDefaults standardUserDefaults] setObject:@"zh-Hans" forKey:appLanguage];
        } else if ([language hasPrefix:@"zh-TW"] || [language hasPrefix:@"zh-HK"] || [language hasPrefix:@"zh-Hant"]) {
            [[NSUserDefaults standardUserDefaults] setObject:@"zh-Hant" forKey:appLanguage];
        } else if ([language hasPrefix:@"en"]) {
            [[NSUserDefaults standardUserDefaults] setObject:@"en" forKey:appLanguage];
        }else{
            [[NSUserDefaults standardUserDefaults] setObject:@"zh-Hans" forKey:appLanguage];
        }
    }

注:由于繁體又有臺(tái)灣繁體和香港繁體之分,所以代碼中也做出了相應(yīng)的處理;

╮(╯▽╰)╭ 到了這里基本上算是完成了多語(yǔ)言版本的工作了,但是,但是,但是,這只是完成了項(xiàng)目起步期,項(xiàng)目中還不存在大量的中文字符串的情況;暫時(shí)先不考慮項(xiàng)目已經(jīng)開(kāi)發(fā)完成的情況,接下來(lái)先來(lái)優(yōu)化下,我們剛剛寫(xiě)過(guò)的代碼;
對(duì)于showLbl方法中的內(nèi)容,可以定義成宏,以供項(xiàng)目中,任何地方需要多元化時(shí)的使用;

 #define ASLocalizedString(key)  [NSString stringWithFormat:@"%@", [[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"appLanguage"]] ofType:@"lproj"]] localizedStringForKey:(key) value:nil table:@"ASLocalized"]]

為了方便,我將showLbl 中取key對(duì)應(yīng)的語(yǔ)言內(nèi)容,封裝進(jìn)了一個(gè)帶參數(shù)的宏中;

使用起來(lái)就很Easy了,只需要這樣使用即可:ASLocalizedString(@"showTxt")

原文鏈接:http://www.devashen.com/blog/archives/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,520評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,362評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,805評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,541評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,896評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,062評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,608評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,356評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,555評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,769評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,175評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,489評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,289評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,516評(píng)論 2 379

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