Developer Tools 进阶 25m
使用 Xcode 构建本地化友好的布局
Build localization-friendly layouts using Xcode
2020年6月24日
一句话判断
如果你的 App 要做国际化,这场 Session 直接告诉你哪些布局习惯会给翻译后的界面埋坑,以及 Xcode 12 提供了什么工具来提前发现这些问题。
这场 Session 讲了什么
这场 Session 聚焦于如何在 Xcode 中构建对本地化友好的 UI 布局。演讲者从一个核心事实出发:翻译后的文本长度和排版方向可能与原始语言截然不同。德语文本通常比英文长 30%,阿拉伯语和希伯来语是从右到左(RTL)排列的,中日韩文字的排版规则也完全不同。如果你的布局没有考虑到这些差异,本地化之后界面就会崩。
演讲者首先介绍了 Auto Layout 在本地化场景下的最佳实践——如何用Leading/Trailing约束替代Left/Right,如何设置内容压缩阻力和内容拥抱优先级来应对不同文本长度。然后展示了 Xcode 12 的新功能:可以在 Interface Builder 中直接预览不同语言和地区的布局效果,无需真正添加翻译文件。
Session 后半部分讨论了国际化相关的具体技术细节,包括伪本地化(Pseudolocalization)的使用、国际化字符串的提取流程,以及如何在 Asset Catalog 中管理本地化的图片资源。
值得深挖的点
- 伪本地化的价值:Xcode 支持在 Scheme 设置中开启伪本地化,它会自动将英文文本替换为带附加字符的模拟翻译文本(如 “[Åñãy träñslåtïöñ tëxt]"")。这让你在没有任何翻译文件的情况下就能发现布局溢出、截断和重叠问题。很多团队跳过了这一步,结果本地化之后才暴露大量 UI 缺陷。
- RTL 布局的约束陷阱:使用 Left/Right 约束在 RTL 语言下不会自动翻转,这是最常见的国际化布局错误。必须统一使用 Leading/Trailing,并在代码中避免硬编码方向假设。
代码片段
// 正确:使用 Leading/Trailing 约束(支持 RTL)
NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
])
// 错误:使用 Left/Right 约束(RTL 下不会翻转)
// NSLayoutConstraint.activate([
// titleLabel.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 16),
// titleLabel.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -16),
// ])
// 设置内容压缩阻力优先级,防止文本被截断
titleLabel.setContentCompressionResistancePriority(
.required, for: .horizontal
)
subtitleLabel.setContentCompressionResistancePriority(
.defaultHigh, for: .horizontal
)
// 多行文本支持
titleLabel.numberOfLines = 0 // 允许无限行
titleLabel.lineBreakMode = .byWordWrapping
// 处理复数和性别变化的本地化
let format = NSLocalizedString(
"items.count",
comment: "Number of items in cart"
)
// Localizable.stringsdict 中定义复数规则
// 英语: 1 item / %d items
// 俄语: 需要 0/1/2-4/5+ 四种形式
label.text = String.localizedStringWithFormat(format, itemCount)
最佳实践
- 所有约束一律使用 Leading/Trailing 而非 Left/Right,这是零成本的 RTL 适配
- 开启伪本地化(Scheme > Run > Arguments > -AppleLanguages “(en-XL)“)提前发现布局问题
- 文本标签始终设置 numberOfLines = 0 或合理的最大行数,不要假设文本只会占一行
- 使用 Size Classes 适配不同语言的排版需求,而非为每种语言单独调整布局
- Asset Catalog 中的方向性图片(如箭头)使用 “Direction” 属性设置为 “Left to Right, Mirrors”
还有什么值得关注
- SwiftUI 的布局默认就是本地化友好的,自动处理 RTL 和文本长度变化
- Xcode 的 Export for Localization 功能现在支持 String Catalog,管理翻译比以前方便很多
- 搭配 “What’s new in Xcode 12” 一起看,可以了解编辑器对国际化开发的整体改进
WWDC 2020