Đa ngôn ngữ trong iOS
Để xét đa ngôn ngữ thường có 2 cách: theo App với theo Device Theo app tức là 1 bạn sẽ lưu 1 biến ở UserDefaults trong App để phân biệt language nào, rồi dựa đó mà set language Theo device, app của bạn sẽ set language theo device. (Ví dụ phần setting của Device của bạn để tiếng Nhật, thì app ...
Để xét đa ngôn ngữ thường có 2 cách: theo App với theo Device
- Theo app tức là 1 bạn sẽ lưu 1 biến ở UserDefaults trong App để phân biệt language nào, rồi dựa đó mà set language
- Theo device, app của bạn sẽ set language theo device. (Ví dụ phần setting của Device của bạn để tiếng Nhật, thì app bạn sẽ set là ngôn ngữ tiếng Nhật) Nhưng dù theo cách nào đi nữa, chắc chắn bạn phải có nhưng file chứa ngôn ngữ tương ứng của nó, bao gồm key và value tương ứng của ngôn ngữ đó
* Ý tưởng ban đầu - set language theo View cha
Dùng luôn text trên file Xib hay StoryBoard làm key luôn (thường làm bằng tiếng Anh) Sau đó tạo các file Localizable trong các ngôn ngữ còn lại (Demo sau của mình làm đa ngôn ngữ cho English, Indonesian, Japanese, Thai, Vietnamese)
Khoan đã, ban đầu download source code trước nhé: https://github.com/QuizSystem/MultiLanguageSwift3 Vừa nhìn source code vừa đọc hướng dẫn mình dưới đây cho dễ hiểu hơn nhé
Trong demo này mình có 3 file
- File ViewController.swift: file này làm cái xử lý UI chính của demo này
- File Language.swift: file này đơn giản chỉ là từ key lấy ra ngôn ngữ tương ứng của nó thôi
- File BaseUIView.swift (chỗ ý tưởng của mình đây)
Ý tưởng mình là sẽ có 2 mảng, 1 mảng chứa các View (có thể là UIButton, UILabel, UITextField), 1 mảng chứa các key tương ứng rồi duyệt xét lại ngôn ngữ cho nó.
* Tiếp tục triển khai thực tế - set language cho các View con: UIButton, UILabel, UITextField luôn
- Tự set language lại luôn trong file Xib, StoryBoard dựa vào key
- Không dùng mảng để lưu lại các View các Key như trên mà sẽ để nó tự set language lại cho nó
Nói suông thế có vẻ hơi khó hiểu, cùng đọc source code nhé https://github.com/QuizSystem/MultiLanguageiOS
Mình viết 1 extension cho UIView
extension UIView { func onUpdateLocale() { for subView in self.subviews { subView.onUpdateLocale() } } }
mục đích để từ View cha gọi tới các view con gọi hàm thay đổi ngôn ngữ onUpdateLocale, nếu trong view con đó mà có view con khác nữa thì cũng gọi onUpdateLocale tiếp. Mục đích duyệt tất cả các View để thay đổi ngôn ngữ. Ta chỉ cần gọi từ view cha lớn nhất thì tất cả các view con sẽ được cập nhận lại ngôn ngữ. self.view.onUpdateLocale() Tương ứng mỗi UIButton, UILabel, UITextField mình sẽ tạo 1 class con kế thừa, override lại hàm set text để làm đa ngôn ngữ Ví dụ LocalizableButton kế thừa từ UIButton
import UIKit class LocalizableButton: UIButton { private var localizeKey: String? override func awakeFromNib() { super.awakeFromNib() localizeKey = currentTitle setTitle(localizeKey, for: .normal) } override func setTitle(_ title: String?, for state: UIControlState) { localizeKey = title super.setTitle(LocalizationHelper.shared.localized(localizeKey), for: state) } override func onUpdateLocale() { super.onUpdateLocale() setTitle(localizeKey, for: .normal) } }
Tương tự vậy UILabel, UITextField trong source code demo trên mình đã có. Như vậy nếu làm như trên, mỗi khi tạo 1 Button hay 1 Label, 1 TextField nào đó bạn nhớ thêm các class quản lý tương ứng cho nó LocalizableButton, LocalizableLabel và LocalizableTextFiled (tên class con mình đặt trong demo như thế) thì khi bạn set ở trên file Xib hay StoryBoard chỉ cần để key nó sẽ tự nhận ngôn ngữ.
Còn khi xử lý ngôn ngữ bằng code, bạn có thể làm đa ngôn ngữ từ key của nó, dùng class SingleTon để set (chính là class LocalizationHelper trong demo) hoặc bạn viết luôn 1 extension cho String để làm đa ngôn ngữ luôn
import Foundation extension String { var localized: String { let currentLocale = Preferences.shared.currentLocale() guard let bundlePath = Bundle.main.path(forResource: currentLocale, ofType: "lproj"), let bundle = Bundle(path: bundlePath) else { return self } return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "") } }
Sau mỗi String chỉ việc gọi tới localized là làm đa ngôn ngữ rồi.
Còn vấn đề, nếu muốn làm Setting chuyển ngôn ngữ trong App. Ta dùng UserDefaults để lưu lại mã ngôn ngữ, để biết và có thể set lại ngôn ngữ (chính là class Preferences trong demo đó). Bạn nhớ khi set lại ngôn ngữ, nhớ gọi thêm self.view.onUpdateLocale() để tất cả các view cập nhật lại ngôn ngữ nhé.
* Bonus thêm - set language theo Device:
Bài viết sau khá hay và cơ bản, hướng dẫn làm bằng Objective C, hướng dẫn bạn làm đa ngôn ngữ theo Device Đa ngôn ngữ cho Text với Hình Ảnh