32. 多语言本地化
本地化的关键是“可维护 + 可扩展”。不要把文案写死在代码里,统一使用字符串表与格式化工具。
一、Localizable.strings
// 使用 key,而不是直接写文案
let title = NSLocalizedString("home.title", comment: "")
Localizable.strings 示例:
"home.title" = "首页";
"home.subtitle" = "欢迎使用";
二、指定字符串表
当模块较多时,用表区分功能。
let title = NSLocalizedString("login.title", tableName: "Login", bundle: .main, value: "", comment: "")
三、复数与 .stringsdict
let count = 3
let text = String.localizedStringWithFormat(NSLocalizedString("item.count", comment: ""), count)
Localizable.stringsdict 示例:
<key>item.count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@items@</string>
<key>items</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>%d 条</string>
<key>other</key>
<string>%d 条</string>
</dict>
</dict>
四、日期与数字格式化
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "zh_CN")
formatter.dateStyle = .medium
formatter.timeStyle = .short
let text = formatter.string(from: Date())
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "fr_FR")
numberFormatter.numberStyle = .decimal
let value = numberFormatter.string(from: 1234567) ?? ""
五、相对时间
let formatter = RelativeDateTimeFormatter()
formatter.locale = Locale(identifier: "zh_CN")
let text = formatter.localizedString(for: Date().addingTimeInterval(-3600), relativeTo: Date())
六、RTL 适配
- 约束使用
leading/trailing - 文本对齐使用
.natural
label.textAlignment = .natural
view.semanticContentAttribute = .unspecified
多语言不是翻译一次就结束,关键是保持文案可维护、格式化一致、布局不崩。