由 林俊杰 (@jjlin) 完成
在英语中,一个词可以是单数或复数(例如1天,2天,10天)。某些语言,如中文,只有一种形式(例如1天,2天,10天),而其他语言,如俄语,则有三种(1 день,2 дня,10 дней)。
Mozilla 已经为所有语言制定了一套17个复数规则的集合。这些规则可以在以下位置找到:https://mdn.org.cn/en/Localization_and_Plurals
JJPluralForm
是从 Mozilla 的 PluralForm
中改编出来的,用于处理 Objective-C 项目中的复数形式。
已扩展某些复数规则,以包含额外的复数规则。例如,尽管中文通常只有一种复数形式,但在某些情况下,可能需要多达三种不同的复数形式。
例如,“每 N 个月”这个短语在英语中可以本地化为“每月”,“每两个月”和“每六个月”。或者更自然地,它可以本地化为“每月”,“每两个月”和“每六个月”。
在中文中,这将是“每月”,“每两个月”和“每 6 个月”。单一复数形式可能会导致本地人听起来不自然的短语,例如“每 2 个月”。
将 JJPluralForm
头文件导入任何需要本地化复数形式的实现文件。
#import "JJPluralForm.h"
从 JJPluralForm.h
选择一个合适的规则,并将其添加到每个 Localizable.strings 文件的顶部。
例如,将以下内容
"JJ_PLURAL_FORM_RULE" =
"1";
添加到 English 版本的 Localizable.strings
文件中,将指定 English 本地化文件使用复数规则编号1,该规则有2种形式:1) 是一个,2) 其他所有内容。
在 JJPluralForm.h
中定义了一个便利宏 kJJPluralFormRule
,该宏可用于获取在您的 Localizable.strings
中定义的复数规则。由于此宏返回一个字符串,因此在将规则传递给 JJPluralForm
时,您需要使用 [kJJPluralFormRule integerValue]
将其转换为整数。
从 JJPluralForm
2.0 开始,您可以使用以下方式配置 JJPluralForm
[JJPluralForm setPluralRule:[kJJPluralFormRule integerValue]];
这允许您使用新方法 +pluralStringForNumber:withPluralForms:
,在本地化字符串时无需指定复数规则。
要将类似“N 天(s)”这样的词组本地化,请将所有复数形式按顺序放入 Localizable.strings
文件中,顺序与 JJPluralForm.h
中列出的一致,并用分号分隔
"N_DAYS_PLURAL_STRING" =
"%@ day;%@ days";
要为“N 天(s)”表达式获取正确的复数形式,可以使用以下任一方法:
[JJPluralForm pluralStringForNumber:N
withPluralForms:NSLocalizedString(@"N_DAYS_PLURAL_STRING", @"")
usingPluralRule:[kJJPluralFormRule integerValue]
localizeNumeral:YES];
其中 N
是限定数。如果你想让返回字符串中的数字根据当前区域格式本地化,可以向 localizeNumeral
传递 YES
。这主要影响使用不同数字符号集的区域,例如阿拉伯语。
如果你之前已经使用 +setPluralRule:
配置了默认复数规则,则可以使用更简短的方法来获取正确的复数形式,而无需每次指定复数规则。
[JJPluralForm pluralStringForNumber:N
withPluralForms:NSLocalizedString(@"N_DAYS_PLURAL_STRING", @"")];
默认情况下,JJPluralForm
使用分号分隔复数形式。从 2.0 版本开始,你可以指定一个自定义分隔符。例如,如果 N_DAYS_PLURAL_STRING
使用管道字符(|
)分隔,即 %@ 天|%@ days
,则可以使用此方法获取正确的复数形式
[JJPluralForm pluralStringForNumber:N
withPluralForms:NSLocalizedString(@"N_DAYS_PLURAL_STRING", @"")
separatedBy:@"|"
usingPluralRule:[kJJPluralFormRule integerValue]
localizeNumeral:YES];
默认情况下,JJPluralForms
初始化并缓存了一个设置为 NSNumberFormatterNoStyle
的 NSNumberFormatter
。尽管名称中提到了样式,但使用此格式化程序格式化数字的效果是使数字以区域正确的脚本显示(例如,阿拉伯用户使用的 东方阿拉伯数字)。
新版本 2.1 中,你可以使用 +setDefaultNumberFormatter:
提供自家的已缓存数字格式化程序。这允许你在使用 JJPluralForm
本地化数字时自定义所有方面的数字格式化方式,例如分隔数字群(例如 1,000,000 与 1000000)。
在调用以下方法时:
- pluralStringForNumber:withPluralForms:
数字会使用缓存数字格式化程序进行格式化和本地化,除非使用 +setShouldLocalizeNumeral:
禁用了本地化。在调用以下方法时:
- pluralStringForNumber:withPluralForms:usingPluralRule:localizeNumeral:
- pluralStringForNumber:withPluralForms:separatedBy:usingPluralRule:localizeNumeral:
只有当 localizedNumeral
为 YES
时,数字才会使用缓存的数字格式化程序进行格式化和本地化。
新版本 2.1 中,你可以为每次调用 pluralStringForNumber:
使用此方法提供一个临时的 NSNumberFormatter
来格式化数字
- pluralStringForNumber:withPluralForms:separatedBy:usingPluralRule:numberFormatter:
示例代码进一步说明了此方法的使用。
代码可从以下地址下载:https://github.com/junjie/JJPluralForm
此源代码形式受 Mozilla 公共许可证第 2.0 版的条款约束。如果本文件未随此文件分发包含 MPL 的副本,您可以在 http://mozilla.org/MPL/2.0/ 获得一份。
在应用程序的关于页面中进行归属是受欢迎的。
包含 JJPluralForm 代码,由 Lin Junjie 提供