Get it right (to left)
System & Services 进阶 20m

搞定从右到左的语言支持

Get it right (to left)

2022年6月6日

在 Apple 官方观看视频

一句话判断

阿拉伯语和希伯来语的 RTL 适配比你想象的复杂,但 Apple 的框架已经帮你处理了大部分工作——前提是你知道哪些地方需要手动介入。

这场 Session 讲了什么

阿拉伯语是 Apple 平台使用量前十的语言之一。RTL(Right-to-Left)语言不只是文字方向反转——它影响整个 UI 布局,从工具栏到侧边栏,从图标到数字显示。

Session 系统性地覆盖了 RTL 适配的六大领域:文本方向与对齐、图标镜像、控件方向、UI 布局、阿拉伯数字显示、以及测试方法。

好消息是,Apple 的 UI 框架默认帮你处理了大量 RTL 适配:CoreText 自动处理双向文本排版,UIKit/SwiftUI 自动设置文本方向和对齐,系统控件自动翻转。但图标、自定义布局和特定控件方向需要你手动处理。

值得深挖的点

  • 自然对齐 vs 强制对齐:UI 控件默认使用”自然对齐”(Natural Alignment),在 RTL 语言下自动右对齐。如果你硬编码了 .left 对齐,RTL 布局就会出错。应该使用 .leading 代替 .left
  • 图标的 RTL 处理:在 Xcode 的 Asset Catalog 中,每个 Image Set 都有 RTL 变体。系统可以自动镜像图标,也可以手动提供 RTL 版本。关键规则是:有方向性的图标(如返回箭头)需要翻转,无方向的图标(如加号)不需要。
  • 双向文本的复杂性:阿拉伯语段落中的数字仍然从左到右显示,英文人名也保持原始方向。这意味着一段文字可能包含多个方向的片段。CoreText 自动处理,但如果你用自定义布局引擎,需要自己处理 bidi 算法。
  • 数字显示的区域差异:阿拉伯语区域不一定使用阿拉伯-印度数字。大部分阿拉伯语用户更习惯西阿拉伯数字(0-9)。Apple 的 NumberFormatter 根据具体区域自动选择。

代码片段

// SwiftUI 中使用语义化的方向 API
HStack {
    Text(" Leading")
    Spacer()
    Text("Trailing ")
}
// 不要用 .left/.right,用 .leading/.trailing

// 检查当前布局方向
let isRTL = Locale.current.language.characterDirection == .rightToLeft

// 在 SwiftUI 中适配方向
Image(systemName: "chevron.right")
    // 自动在 RTL 下翻转为 chevron.left
    .environment(\.layoutDirection, .rightToLeft)

// Xcode Asset Catalog 中设置 RTL 变体
// 方法一:在 Imageset 编辑器中勾选 "Right-to-Left"
// 系统自动水平镜像
// 方法二:提供单独的 RTL 图片资源
// 数字格式化的 RTL 处理
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "ar_SA")  // 沙特阿拉伯
formatter.string(from: 42)  // 可能返回 "٤٢" 或 "42",取决于区域

// 日期格式化也自动适配
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "he_IL")  // 以色列
dateFormatter.dateStyle = .long

最佳实践

  • 永远使用 .leading/.trailing 而非 .left/.right
  • 有方向性的图标提供 RTL 变体,在 Asset Catalog 中配置
  • 在自定义布局中检查 userInterfaceLayoutDirection 属性
  • 不要假设数字总是从左到右——用 NumberFormatter
  • 测试时在系统设置中切换语言为阿拉伯语或希伯来语,全面检查 UI
  • 用 SwiftUI Preview 配合 \.layoutDirection 环境值快速验证 RTL 布局

还有什么值得关注

  • Apple 支持 15 种 RTL 语言,不仅限于阿拉伯语和希伯来语
  • SwiftUI 的 RTL 支持比 UIKit 更完善,新项目优先考虑 SwiftUI
  • “Creating Great Localizations” 和 “Localization” 等文档是 RTL 之外的国际化参考
  • Auto Layout 在 RTL 下的行为与 Leading/Trailing 约束一致,但如果你用了 Left/Right 约束就会出问题
WWDC 2022