[译]SwiftUI 的多语言本地化和预览

原文:Localization with SwiftUI, how to preview your localized content

我很好奇最近推出的 SwiftUI 的预览功能能否用来加速多语言本地化的测试,并确保你的应用能适配任何语言。

首先创建一个简单的视图。

localization-swiftui-start

从这个简单的视图中,我需要提取硬编码文本,以便能够对其进行本地化。为此,我在项目中创建了一个 Localizable.strings 文件来表示每种语言。到目前为止,没有什么新的东西。

现在加上法语和简体中文,看看会发生什么。

localization-swiftui-strings

运行这已经很不错了并设置为不同地区,确实可以看到不同的翻译。但如果要测试多语言和调整 UI 就相当繁琐了。

这就可以看到 SwiftUI 真正牛逼的地方了。苹果推出了环境变量,其中一个是专门针对区域和语言的可以用来完成这个功能的预览。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, .init(identifier: "en"))
    }
}

通过设置新的 Locale 标识符(如 frzh),预览会自动重新加载最新的翻译。相当强大!

localization-swiftui

这已经挺不错了。

再深入研究一下,我们发现 TextButton 控件支持使用 LocalizableStringKey 来初始化,这就是它们能获取到正确翻译的方式。

init(_ key: LocalizedStringKey, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil)

但是使用硬编码字符串很容易出现拼写错误。

过去我一直在使用代码生成工具来处理翻译,我个人是 SwiftGen 的粉丝,但它只能支持模拟器还不支持这个预览。

但是现在我们知道了 View 是如何使用 LocalizableStringKey 的,所以我们可以利用代码生成工具来进行翻译。我们也可以创建我们自己的枚举数据来避免那些拼写错误,并允许自动补完,怎么方便怎么来。

在调整了 SwiftGen 模板之后,我创建了一个可以很好地适应 SwiftUI 的模板。这是它的一部分。

enum Translation {

    static var welcomeToMyApp: LocalizedStringKey {
        return "Welcome into my app"
    }

    static var startByTappingThisButton: LocalizedStringKey {
        return "Start by tapping this button"
    }

    static var startBrowsing: LocalizedStringKey {
        return "Start browsing"
    }
}

现在用刚刚生成的名字来替代硬编码字符串。

struct ContentView: View {

    var body: some View {

        VStack(spacing: 40) {
            VStack(alignment: .leading) {
                Text(Translation.welcomeToMyApp)
                    .font(.title)

                Text(Translation.startByTappingThisButton)
                    .font(.body)
            }

            Button(Translation.startBrowsing) {
                // TODO
            }
            .foregroundColor(.white)
            .padding()
            .background(Color(#colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1)))
            .cornerRadius(10)

        }
        .padding()
        .border(Color(#colorLiteral(red: 0.1215686277, green: 0.01176470611, blue: 0.4235294163, alpha: 1)), width: 1)

    }
}

我有点好奇像日期、货币、数字格式这些本地化,能不能用这种方式实现。但我觉得这些不是在 View 端生成的,而是在 ViewModel 或任何地方的计算逻辑上生成的,所以我在这里没有表示出来。

我相信我们可以更进一步,尝试着从你的内容中预览其他可本地化的元素,比如颜色、图片和任何静态的东西。

就这样,使用代码生成工具和 SwiftUI 的预览功能来帮助我们在短时间内快速完成不同语言和不同设备的适配。

Happy coding!

[全文完]

# 补充

文中创建几个多语言文件的步骤:

  1. 直接创建一个 strings 类型的文件 Localizable.strings
  2. 选中 Localizable.strings 然后在右侧信息面板中点击 Localization 按钮
  3. PROJECT / Info / Localizations 创建其他语言的文件

localization-swiftui-strings3

Xcode 的翻译的功能做的不行呀,很多年前 Android Studio 就实现了用一个类似表格的编辑器来实现翻译管理。