在 APP 內切換語系(iOS Localized)

延續上一篇關於多國語系的那些事後,該篇來介紹如何在 App 內切換語系,而切換語系是站在使用者的角度來看的

法蘭克的 iOS 世界
6 min readApr 5, 2018

而站在開發者的角度來看的話,並不是寫程式去改變整個 OS 系統的語系,而是依使用者所切換的語系別去讀取 Bundle 裡的語系檔罷了

前置作業

為了模擬切換語系的情境,法蘭克使用 Storyboard 搭配 SegmentedControl 和 ContainerView 建置了情境,多國語系檔的建置在上篇已說明過,所以這邊就跳過,如果不知從何下手的,可從此下載空專案開始,而該專案所使用到的 SegmentControl 和 ContainerView,等法蘭克有空再來分享囉!該篇只要專注於語系的切換即可。

情境說明

▼依使用者選中的 SegmentControl 的 Tab 呈現不同的語系,分別為英文(預設)、簡體、繁體。

SegmentControl + ContainerView

1 => SegmentControl 有三個 Tab 分別為英文、簡體、繁體,並依照使用者所選中的 Tab 呈現不同的語系。

2 => ViewController 裡的三個 ContainerView 分別對應到圖上第 3 點的 EnglishViewController、SimplifiedViewController、TraditionalViewController。

Segment Control Action

▲點擊 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」讓我持續提供好文章給您。

--

--