SwiftUI自动字符串定位问题

SwiftUI自动字符串定位问题,swiftui,Swiftui,我一直在做一个SwiftUI应用程序的本地化工作,我遇到了一个与本地化相关的情况,我不太了解(首先,我还不是很精通SwiftUI) 据我所知,至少在iOS 14中,SwiftUI几乎自动将本地化应用于所有“普通”字符串(只要我设置了正确的本地化文件,我就会这样做)。但是,我有两个相同字符串文本的实例-一个得到自动本地化处理。另一个没有 这就是我想弄清楚的情况 我有以下代码: NavigationView { NavigationLink(destination: CalendarSettin

我一直在做一个SwiftUI应用程序的本地化工作,我遇到了一个与本地化相关的情况,我不太了解(首先,我还不是很精通SwiftUI)

据我所知,至少在iOS 14中,SwiftUI几乎自动将本地化应用于所有“普通”字符串(只要我设置了正确的本地化文件,我就会这样做)。但是,我有两个相同字符串文本的实例-一个得到自动本地化处理。另一个没有

这就是我想弄清楚的情况

我有以下代码:

NavigationView {
  NavigationLink(destination: CalendarSettingsView()) {
    SettingsNavLinkView(label: "Calendar") // <- this doesn't get localized
  }
}

此外,
CalendarSettingsView
将其标题定义为:

struct CalendarSettingsView: View {
  var body: some View {
    ScrollView {
       //some code
    }
    .navigationBarTitle("Calendar", displayMode: .inline) // <- "Calendar" here does get localized
  }
}
但我为什么要这么做?为什么“日历”字符串在传递到
SettingsNavLinkView
时没有按照此代码
SettingsNavLinkView(标签:“日历”)
自动本地化

SwiftUI本地化中的一个bug?我对本地化工作的不完全理解? 对于“简单字符串”,我不想求助于
LocalizedStringKey
。但从“自动”本地化的真正工作原理来看,我不确定我所要求的是否有效


任何想法都值得赞赏。谢谢

因为不同的
文本
构造函数是为文本字符串和变量字符串推断的,这在SwiftUIAPI中有记录

/// Creates a text view that displays a stored string without localization.
///
/// Use this intializer to create a text view that displays — without
/// localization — the text in a string variable.
///
///     Text(someString) // Displays the contents of `someString` without localization.
///
/// SwiftUI doesn't call the `init(_:)` method when you initialize a text
/// view with a string literal as the input. Instead, a string literal
/// triggers the ``Text/init(_:tableName:bundle:comment:)`` method — which
/// treats the input as a ``LocalizedStringKey`` instance — and attempts to
/// perform localization.
///
/// By default, SwiftUI assumes that you don't want to localize stored
/// strings, but if you do, you can first create a localized string key from
/// the value, and initialize the text view with that. Using a key as input
/// triggers the ``Text/init(_:tableName:bundle:comment:)`` method instead.
///
/// - Parameter content: The string value to display without localization.
public init<S>(_ content: S) where S : StringProtocol
我建议使用以下代码(使用Xcode 12.1/iOS 14.1测试)

struct SettingsNavLinkView:View{
变量标签:字符串
var body:一些观点{

Text(LocalizedStringKey(label))//根据苹果的文档,这是正确的。文字字符串会自动本地化,变量不会。按钮文本也不会。它的“为什么”对我来说仍然毫无意义。另外值得一提的是,苹果内置的“导出本地化…”不会自动导出LocalizedStringKey(标签)。它必须手动添加到可本地化的.strings文件中。因此,我仍然认为NSLocalizedString()是一种更好的方法。本文对此进行了解释:
struct SettingsNavLinkView: View {
  var label:String
  let localizedLabel = LocalizedStringKey(label) // <-- NEW

  var body: some View {
    Text(localizedLabel) // <-- UPDATED to use localizedLabel instead of label
  }
}
/// Creates a text view that displays a stored string without localization.
///
/// Use this intializer to create a text view that displays — without
/// localization — the text in a string variable.
///
///     Text(someString) // Displays the contents of `someString` without localization.
///
/// SwiftUI doesn't call the `init(_:)` method when you initialize a text
/// view with a string literal as the input. Instead, a string literal
/// triggers the ``Text/init(_:tableName:bundle:comment:)`` method — which
/// treats the input as a ``LocalizedStringKey`` instance — and attempts to
/// perform localization.
///
/// By default, SwiftUI assumes that you don't want to localize stored
/// strings, but if you do, you can first create a localized string key from
/// the value, and initialize the text view with that. Using a key as input
/// triggers the ``Text/init(_:tableName:bundle:comment:)`` method instead.
///
/// - Parameter content: The string value to display without localization.
public init<S>(_ content: S) where S : StringProtocol
/// Creates a text view that displays localized content identified by a key.
///
/// Use this intializer to look for the `key` parameter in a localization
/// table and display the associated string value in the initialized text
/// view. If the initializer can't find the key in the table, or if no table
/// exists, the text view displays the string representation of the key
/// instead.
///
///     Text("pencil") // Localizes the key if possible, or displays "pencil" if not.
///
/// When you initialize a text view with a string literal, the view triggers
/// this initializer because it assumes you want the string localized, even
/// when you don't explicitly specify a table, as in the above example. If
/// you haven't provided localization for a particular string, you still get
/// reasonable behavior, because the initializer displays the key, which
/// typically contains the unlocalized string.
///
/// If you initialize a text view with a string variable rather than a
/// string literal, the view triggers the ``Text/init(_:)-9d1g4``
/// initializer instead, because it assumes that you don't want localization
/// in that case. If you do want to localize the value stored in a string
/// variable, you can choose to call the `init(_:tableName:bundle:comment:)`
/// initializer by first creating a ``LocalizedStringKey`` instance from the
/// string variable:
///
///     Text(LocalizedStringKey(someString)) // Localizes the contents of `someString`.
///
/// If you have a string literal that you don't want to localize, use the
/// ``Text/init(verbatim:)`` initializer instead.
///
/// - Parameters:
///   - key: The key for a string in the table identified by `tableName`.
///   - tableName: The name of the string table to search. If `nil`, use the
///     table in the `Localizable.strings` file.
///   - bundle: The bundle containing the strings file. If `nil`, use the
///     main bundle.
///   - comment: Contextual information about this key-value pair.
public init(_ key: LocalizedStringKey, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil)
struct SettingsNavLinkView: View {
  var label: String
  
  var body: some View {
    Text(LocalizedStringKey(label))     // << inline !!
  }
}