在 APP 內切換語系(iOS Localized)
延續上一篇關於多國語系的那些事後,該篇來介紹如何在 App 內切換語系,而切換語系是站在使用者的角度來看的
而站在開發者的角度來看的話,並不是寫程式去改變整個 OS 系統的語系,而是依使用者所切換的語系別去讀取 Bundle 裡的語系檔罷了
前置作業
為了模擬切換語系的情境,法蘭克使用 Storyboard 搭配 SegmentedControl 和 ContainerView 建置了情境,多國語系檔的建置在上篇已說明過,所以這邊就跳過,如果不知從何下手的,可從此下載空專案開始,而該專案所使用到的 SegmentControl 和 ContainerView,等法蘭克有空再來分享囉!該篇只要專注於語系的切換即可。
情境說明
▼依使用者選中的 SegmentControl 的 Tab 呈現不同的語系,分別為英文(預設)、簡體、繁體。
1 => SegmentControl 有三個 Tab 分別為英文、簡體、繁體,並依照使用者所選中的 Tab 呈現不同的語系。
2 => ViewController 裡的三個 ContainerView 分別對應到圖上第 3 點的 EnglishViewController、SimplifiedViewController、TraditionalViewController。
▲點擊 SegmentControl 所會觸發的 Action,因 ContainerView 有著 Reuse 的特性,故物件一生成即會存在,所以這邊依使用者選中的 Tab 來顯示和隱藏 ContainView。
▲英文、簡體、繁體的語系檔裡皆已存在 key 為 Hello 的多國語
實作
- 將從 Bundle 裡取得多國語系的物件模組化(LocalizeUtils.swift)
- 在 EnglishViewController.swift、SimplifiedViewController.swift、TraditionalViewController.swift 加入利用 LocalizeUtils.swift 從 Bundle 裡取得多國語系的文字
將從 Bundle 裡取得多國語系的物件模組化(LocalizeUtils.swift)
該物件會在整個 Project 的任何地方被使用到,為了節省記憶體,故法蘭克採用單例的設計模式來設計它,此舉的好處也方便直接套用在其它新專案。
▼生成一物件 LocalizeUtils.swift,並將以下程式碼加入
第 13~20 行 => 依語系檔裡的 key 取得 value 值,該 function 的第一個參數為多國語系檔的 key 值、第二個參數為多國語系的檔名。第 15~16 行為取得 Bundle 下的的多國語系檔,多國語系檔的副檔名固定為 .lproj,而檔名有以下兩種方式可以得知。
- 在新增語系時
- 在專案下的 Localizable.strings 點選右鍵 → Show in Finder
第 19 行 => 依 key 值和 Bundle 的多國語系檔取得對應的 value 值。
以下這段邏輯今天的範例不會使用到,但這在實際開發中是一定得實作的方法
第 23~44 行 => 該方法會在使用者第一次開啟 App 時依 OS 設定的語系來決定 App 內的語系。第 25 行 => 取得使用者當前設定的語系。
第 26 行 => 依「-」做字串切割。第 30~40 行 => 依取出的字串來決定預設的語系為何,並將結果存放在 UserDefaults key 值為 UserLanguage 的域中以便整個 Project 用。
在 EnglishViewController.swift、SimplifiedViewController.swift、TraditionalViewController.swift 加入利用 LocalizeUtils.swift 從 Bundle 裡取得多國語系的文字
在 EnglishViewController.swift 的 viewWillAppear(_:) 裡加入以下程式碼
withKey => 傳入多國語系檔的 key 值
withLocalizationFileNmae => 多國語系檔名
在 SimplifiedViewController.swift 的 viewWillAppear(_:) 裡加入以下程式碼
在 TraditionalViewController.swift 的 viewWillAppear(_:) 裡加入以下程式碼
以上已完成今天的教學,試著啟動模擬器試試囉!
該範例已放上 GitHub,如有更好的作法或問題都可以留言給法蘭克。
如果您喜歡我的文章,請多按幾下「拍手」給我鼓勵,或是按「follow」讓我持續提供好文章給您。