如何在Swift UI中实现本地化

39

有人可以帮我吗?我找不到任何Swift UI中本地化的描述。 请问有人能否给出建议或更好的示例,例如如何本地化Text()

8个回答

57

当您查看 Text 的文档时,可以看到它在初始化函数中接受的是 LocalizedStringKey 而不是 String:

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

这使得本地化变得非常简单明了。您需要做的就是:

  • 创建一个类型为“字符串文件”的新文件,将其命名为Localizable.strings
  • 选择新文件并导航到右侧面板中的“文件检查器”,然后点击“本地化...”
  • 转到项目文件的“本地化”部分,并将另一种语言添加到列表中 - Xcode会为您创建本地化文件

当您选择您的Localizable.strings文件时,您会看到它包含原始语言和您刚刚添加的语言的文件。在那里,您可以放置您的翻译,即键 - 本地化文本对。

如果您的应用程序中有这样的文本:

Text("Hello World!")

现在您需要将翻译添加到Localizable.strings中:

对于您的基本语言:

"Hello World!" = "Hello World!";

对于您的第二种语言(在这种情况下是德语):

"Hello World!" = "Hallo Welt!";

要查看您的本地化预览,您可以像这样定义它们:

struct ContentViewView_Previews: PreviewProvider {

    static var previews: some View {
        ForEach(["en", "de"], id: \.self) { id in
            ContentView()
                .environment(\.locale, .init(identifier: id))
        }
    }
}

谢谢,这很有帮助!但是我遇到了一些问题,因为已经添加了多种语言。 - Oleh H
问题到底是什么? - LuLuGaGa
7
我找到了问题@LuLuGaGa。事实证明,我没有严格按照指示去做,就像我之前所说的那样。我的本地化字符串文件在子文件夹中。将其放在项目级别上,它就能正常工作了。 - Joseph Beuys' Mum
6
我也发现(我认为)将字符串文件命名为除 Localizable 以外的任何名称都意味着它无法工作。 - Joseph Beuys' Mum
1
如果有人感兴趣,我将所有有关SwiftUI本地化的指令整理成了一篇教程:https://www.ibabbleon.com/swiftui_localization_tutorial.html - Localizer
显示剩余7条评论

23

有一件事情,任何我看到的解释都没有很清楚地表明你可能做错的事情。结果证明,只有在传递字面值时,Text("hello")才会被解释为本地化键。如果传递字符串类型的变量,则不会发生这种情况。答案是将变量声明为类型LocalizedStringKey。

  Text("hello") //-> implicitly treats string literal as a key; looks up and displays "Hello World!"
  let cap1:String = "hello"
  Text(cap1)   //-> no lookup for explicit String variable; just displays "hello"
  let cap2:LocalizedStringKey = "hello"
  Text(cap2)   //-> looks up explicit LocalizedStringKey value; displays "Hello World!"

2
如果cap2有动态值的占位符,那么我们该如何传递这个值呢?例如:let cap2: LocalizedStringKey = "hello %@". 显示字符串将会是"Hello ABC",其中ABC是动态值。 - Rocker
非常感谢,我已经对此感到沮丧并认为没有解决方案。 - Big_Chair

7

在将字符串传递给Text()之前,您可以将其简单地包装在LocalizedStringKey中。

Localizable.strings文件:

"Dismiss" = "关闭";
"Cancel" = "取消";

SwiftUI 视图文件:

Text(LocalizedStringKey("Dismiss"))

不确定这是否曾经是必要的。根据苹果文档当您使用初始化程序Text("Hello")时,SwiftUI会为您创建一个LocalizedStringKey,并使用它来查找Hello字符串的本地化。 - Robin Daugherty

6
对于Swift UI文件,您只需从本地化.strings文件中插入字符串键即可。
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("selectLanguage")
            Text("languagesList")
        }
        
        
        
    }
}

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

这是一个.strings文件的示例。
"selectLanguage" = "Select language";
"languagesList" = "Languages list";

这里是结果:

屏幕截图


5

要本地化您的应用程序,您需要:

  1. 使用SwiftUI元素,如:Text(“Nice”)。 Nice 成为 Localizable.strings 中的键。
  2. 在文本不在SwiftUI元素中的情况下,需要使用NSLocalizedString
  3. 选择您的应用程序目标。
  4. 导出本地化:编辑 -> 导出本地化...
  5. 将导出文件交给翻译人员。
  6. 导入翻译:编辑 -> 导入本地化...

1

要在SwiftUI中使用Localizable,您可以采用以下方式:

导入SwiftUI以在文件中使用LocalizedStringKey

//MARK: - File where you enum your keys to your Localized file
enum ButtonName: LocalizedStringKey {
case submit
case cancel
}

//MARK: - Your Localized file where are your translation
"submit" = "Submit is pressed";
"cancel" = "Cancel";

//MARK: - In your code
let submitButtonName = ButtonName.submit.rawValue
let cancelButtonName = ButtonName.cancel.rawValue

VStack {
Text(submitButtonName)
Text(cancelButtonName)
}

0
我创建了这个自定义的SwiftUI文本。
struct Localized: View {
    var text: String
    var arg: Any?
    var body: some View {
        if let arg = arg {
            if let arg = arg as? [Any] {
                Text(String(format: NSLocalizedString(text, comment: ""), arg.compactMap({String(describing:$0)}).joined(separator: " ")).replacingOccurrences(of: "(null)", with: ""))
            } else {
                Text(String(format: NSLocalizedString("\(text) %@", comment: ""), String(describing: arg)))
            }
        } else {
            Text(LocalizedStringKey(text))
        }
    }
 }

使用方法:

Localized(text: "hello")
Localized(text: "this %@ %@", arg: [4, "a"])

0
2023年WWDC的最新消息:{{link1:String目录}}。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接