在解决了我需要根据第二个参数/变量进行复数的问题后,我还找到了解决您问题的方法,而无需更改参数的顺序或使用代理规则链接。感谢其他发帖者的回答和解决方案,这使我进行了实验并更好地理解.stringsdict
.
我认为我的情况与你的情况很接近,但更容易一些,并且可以帮助你更好地理解字符串格式和规则是如何应用的,所以让我从我的例子开始。
我的情况
我需要构造一个类似1 of 1 item selected
or的字符串1 of 5 items selected
:
let countWithSelectionFormat = NSLocalizedString("%ld of %ld item(s) selected", comment: "Number of items with selection")
let countString = String.localizedStringWithFormat(countWithSelectionFormat, selectedCount, totalCount)
字符串格式%ld of %ld item(s) selected
在这里只是一个占位符,一个别名。它在 中被忽略Localizable.strings
,因为它已在 中首先找到Localizable.stringsdict
。它仅用作 中规则的键Localizable.stringsdict
,但实际上并不用于构造字符串:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>%ld of %ld item(s) selected</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%ld of %#@totalItems@ selected</string>
<key>totalItems</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>%ld item</string>
<key>other</key>
<string>%ld items</string>
</dict>
</dict>
</dict>
</plist>
实际的字符串格式在 中列出NSStringLocalizedFormatKey
,它是%ld of %#@totalItems@ selected
。这里第一个参数selectedCount
是通过 using 传递的%ld
(没有使它成为变量并列出它的规则)。第二个参数totalCount
用%#@totalItems@
变量及其返回1 item
或的规则解析,例如5 items
,从而构造正确的字符串。
如果您需要更改某些语言的输出中参数的顺序,您可以使用%2$#@totalItems@, %1$ld selected
as NSStringLocalizedFormatKey
。
如果需要,您还可以引入第二个变量(和规则)%2$#@totalItems@, %1$#@selectedItems@
:.
你的情况
我的 Swift 代码与您在 Objective-C 中的代码基本相同:
let stringFormat = NSLocalizedString("On %@ there are up to %ld sun hours", comment: "")
let string = String.localizedStringWithFormat(stringFormat, dayString, sunHours)
Localizable.stringsdict
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>On %@ there are up to %ld sun hours</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@day@%#@hours@</string>
<key>day</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>other</key>
<string></string>
</dict>
<key>hours</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>On %1$@ there are no sun hours</string>
<key>one</key>
<string>There is one sun hour on %1$@</string>
<key>other</key>
<string>On %1$@ there are up to %2$ld sun hours</string>
</dict>
</dict>
</dict>
</plist>
在NSStringLocalizedFormatKey
我使用 2 个变量:%#@day@%#@hours@
.
day
变量和规则用于“消耗”第一个参数,dayString
我们在这里不需要任何输出(固定在句子的开头)。我在这里使用了格式值类型d
(如%d
整数),因为我们不需要并且我们无法解析字符串来选择适用的复数规则。我们只使用所需的other
规则,它返回一个空字符串。出于同样的原因,字符串格式中的day
和变量之间没有空格。hours
该hours
变量捕获第二个参数sunHours
,它的规则负责构建实际的输出字符串(在这种情况下是整个句子)。因为我必须从第二个变量的规则中引用两个参数,所以我分别使用%1$@
and%2$ld
来引用dayString
和sunHours
参数。因此,您也可以以任何组合和顺序使用您的变量。
这给出了预期的结果:
String.localizedStringWithFormat(stringFormat, dayString, 0) // On Monday there are no sun hours
String.localizedStringWithFormat(stringFormat, dayString, 1) // There is one sun hour on Monday
String.localizedStringWithFormat(stringFormat, dayString, 5) // On Monday there are up to 5 sun hours
参考:
这两个示例都使用 Swift 5、Xcode 10.2.1、macOS 10.14.5 进行了测试,目标是 macOS 10.12。