Cor*_*ius 5 localization objective-c pluralize ios
我想%@ there are up to %i sun hours用正确的复数翻译字符串.
%@包含一天,%i太阳时.
这是我的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>%@ there are up to %i sun hours</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@hours@</string>
<key>hours</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>i</string>
<key>zero</key>
<string>%@ there are no sun hours</string>
<key>one</key>
<string>There is one sun hour %@ </string>
<key>other</key>
<string>%@ there are up to %i sun hours</string>
</dict>
</dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)
这就是我所说的:
[NSString stringWithFormat:NSLocalizedString(@"%@ there are up to %i sun hours", nil), dayString, sunHours];
Run Code Online (Sandbox Code Playgroud)
无论NSInteger我作为第二个参数传递什么,翻译将始终与"其他"模板一起使用.NSStringLocalizedFormatKey当我使用像%@ %#@hours@它工作的密钥时,我把它缩小到了错误.
我希望字符串参数是本地化的一部分.有没有办法做到这一点?
sta*_*wtf 13
在解决了我需要根据第二个参数/变量进行复数化的问题后,我还找到了解决问题的方法,而无需更改参数的顺序或使用代理规则链接。感谢其他发帖者的答案和解决方案,这使我能够进行实验并更好地理解.stringsdict.
我认为我的情况与您的情况很接近,但更容易一些,并且可以帮助您更好地理解如何应用字符串格式和规则,所以让我从我的示例开始展示。
\n我需要构造一个类似1 of 1 item selectedor 的字符串1 of 5 items selected:
let countWithSelectionFormat = NSLocalizedString("%ld of %ld item(s) selected", comment: "Number of items with selection")\nlet countString = String.localizedStringWithFormat(countWithSelectionFormat, selectedCount, totalCount)\nRun Code Online (Sandbox Code Playgroud)\n字符串格式%ld of %ld item(s) selected在这里只是一个占位符,一个别名。它在 中被忽略Localizable.strings,因为它首先在 中被发现Localizable.stringsdict。它仅用作 中规则的键Localizable.stringsdict,但实际上并不用于构造字符串:
<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>%ld of %ld item(s) selected</key>\n <dict>\n <key>NSStringLocalizedFormatKey</key>\n <string>%ld of %#@totalItems@ selected</string>\n <key>totalItems</key>\n <dict>\n <key>NSStringFormatSpecTypeKey</key>\n <string>NSStringPluralRuleType</string>\n <key>NSStringFormatValueTypeKey</key>\n <string>ld</string>\n <key>one</key>\n <string>%ld item</string>\n <key>other</key>\n <string>%ld items</string>\n </dict>\n </dict>\n</dict>\n</plist>\nRun Code Online (Sandbox Code Playgroud)\n实际的字符串格式在 中列出NSStringLocalizedFormatKey,它是%ld of %#@totalItems@ selected。这里第一个参数selectedCount是通过 using 传递的%ld(不使其可变并为其列出规则)。第二个参数totalCount用%#@totalItems@变量及其规则进行解析1 item,返回 或5 items,从而构造正确的字符串。
如果您需要更改某些语言的输出中参数的顺序,可以使用%2$#@totalItems@, %1$ld selectedas NSStringLocalizedFormatKey。
如果需要,您还可以引入第二个变量(和规则):%2$#@totalItems@, %1$#@selectedItems@。
我的 Swift 代码与 Objective-C 中的代码基本相同:
\nlet stringFormat = NSLocalizedString("On %@ there are up to %ld sun hours", comment: "")\nlet string = String.localizedStringWithFormat(stringFormat, dayString, sunHours)\nRun Code Online (Sandbox Code Playgroud)\nLocalizable.stringsdict:
<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>On %@ there are up to %ld sun hours</key>\n <dict>\n <key>NSStringLocalizedFormatKey</key>\n <string>%#@day@%#@hours@</string>\n <key>day</key>\n <dict>\n <key>NSStringFormatSpecTypeKey</key>\n <string>NSStringPluralRuleType</string>\n <key>NSStringFormatValueTypeKey</key>\n <string>d</string>\n <key>other</key>\n <string></string>\n </dict>\n <key>hours</key>\n <dict>\n <key>NSStringFormatSpecTypeKey</key>\n <string>NSStringPluralRuleType</string>\n <key>NSStringFormatValueTypeKey</key>\n <string>ld</string>\n <key>zero</key>\n <string>On %1$@ there are no sun hours</string>\n <key>one</key>\n <string>There is one sun hour on %1$@</string>\n <key>other</key>\n <string>On %1$@ there are up to %2$ld sun hours</string>\n </dict>\n </dict>\n</dict>\n</plist>\nRun Code Online (Sandbox Code Playgroud)\n在NSStringLocalizedFormatKey我使用2个变量:%#@day@%#@hours@.
变量day和规则用于“消耗”第一个参数dayString,我们在这里不需要任何输出(固定在句子的开头)。我在这里使用了格式值类型d(如%d整数),因为我们不需要,也无法解析字符串来选择适用的复数规则。我们只使用所需的other规则,它返回一个空字符串。出于同样的原因,字符串格式中的day和变量之间没有空格。hours
该hours变量捕获第二个参数sunHours,其规则负责构造实际的输出字符串(在本例中为整个句子)。由于我必须从第二个变量的规则内部引用两个参数,因此我分别使用%1$@和%2$ld来引用dayString和sunHours参数。因此,您还可以以任意组合和顺序使用变量。
这给出了期望的结果:
\nString.localizedStringWithFormat(stringFormat, dayString, 0) // On Monday there are no sun hours\nString.localizedStringWithFormat(stringFormat, dayString, 1) // There is one sun hour on Monday\nString.localizedStringWithFormat(stringFormat, dayString, 5) // On Monday there are up to 5 sun hours\nRun Code Online (Sandbox Code Playgroud)\n这两个示例均使用 Swift 5、Xcode 10.2.1、macOS 10.14.5(针对 macOS 10.12)进行了测试。
\n基于我已经完成的实验,您需要更改参数的顺序.似乎只有第一个可以用作替换规则的控制值.
这本词典
<key>%i hours %@</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@hours@</string>
<key>hours</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>i</string>
<key>zero</key>
<string>%2$@ there are no sun hours</string>
<key>one</key>
<string>There is one sun hour %2$@ </string>
<key>other</key>
<string>%2$@ there are up to %1$d sun hours</string>
</dict>
</dict>
Run Code Online (Sandbox Code Playgroud)
结合
[NSString stringWithFormat:NSLocalizedString(@"%i hours %@", nil), sunHours, dayString];
Run Code Online (Sandbox Code Playgroud)
为我产生预期的结果.请注意,我已将参数索引添加到替换字符串,以便正确放置值.
看起来这些文档在描述这个功能时过于雄心勃勃.例如,标题为"OS X 10.9发行说明"(虽然链接适用于iOS)的文档中给出的示例意味着您应该能够打开第二个参数:
我们通过将整个参数列表应用于每个替换格式说明符来允许递归格式化.
Run Code Online (Sandbox Code Playgroud)@"%d in %d files are selected" = @"%2$#@d_in_d_files_are_selected@"配置字典可以包含
Run Code Online (Sandbox Code Playgroud)"d_in_d_files_are_selected" = { "NSStringFormatSpecTypeKey" = "NSStringPluralRuleType"; // plural type "NSStringFormatValueTypeKey" = "d"; // int argument "zero" = "There is no file"; "one" = "There is a file, and %1$#@it_is_selected@"; "other" = "%1$d in %2$d files are selected"; };
但是根据指南构建字典并没有给出所述结果.(请注意,之后立即给出的示例XML与此字典不匹配.)
可能有一些我误读的东西,(或者可能存在错误),但我无法确切地说明发生了什么.现在,我将离开这个"改变参数顺序将解决你的问题".
从 macOS SDK 10.12/Xcode 8.3 开始,这仍然是一个问题,NSStringLocalizedFormatKey忽略参数编号并使用第一个参数来确定 的复数d_in_d_files_are_selected。但。复数规则格式中的嵌套编号引用确实有效,因此例如"one" = "There is one file, and %2$#@it_is_selected@";将正确使用第二个参数来选择复数规则。这意味着,如果您使用单个other规则创建格式代理,则无需重新排列格式字符串即可实现您想要的行为:
<key>%@ there are up to %i sun hours</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@proxy@</string>
<key>proxy</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>i</string>
<key>other</key>
<string>%2$#@hours@</string>
</dict>
<key>hours</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>i</string>
<key>zero</key>
<string>%1$@ there are no sun hours</string>
<key>one</key>
<string>There is one sun hour %1$@ </string>
<key>other</key>
<string>%1$@ there are up to %2$i sun hours</string>
</dict>
</dict>
Run Code Online (Sandbox Code Playgroud)
请注意,要使其正常工作,您必须在最终格式字符串 ( "%1$@ there are up to %2$i sun hours") 中明确指定参数编号。
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |