2009-10-27 67 views
9

在我的iPhone應用程序,我需要顯示對象計數然後我本地化,因爲英語使得單數和複數的區別,我下面如何本地化iPhone應用程序的數字?

//僞

 
if (objectList.count == 1) 
{ 
    NSLog(@"%@", NSLocalizedString(@"1 object", @"display one objects"); 
} 
else 
{ 
    NSLog(@"%@", NSLocalizedString(@"%d objects", @"display multiple objects"); 
} 

這適用於英語但在許多其他語言中,名詞的複數形式不是簡單地通過添加's'來構造。

As this page explains,有兩件事情可以語言之間的差異:

  • 形式如何複數形式是建立不同。這是 語言有許多 違規的問題。德語,例如, 是一個激烈的案例。雖然英語和德語是 家族(日耳曼語)的一部分,但在 德語中很難找到形成複數名詞形式 (附加's')的幾乎正規的 。
  • 複數形式不同。這對於那些只有羅馬尼亞語 和日耳曼語言經驗的 來說有些令人驚訝,因爲這裏的 號碼是相同的(有兩個)。

我該如何處理我的代碼?

+0

這不是俄羅斯特有的問題 - 有針對你需要的不僅僅是一個複數更多其他語言。 – 2009-10-27 17:34:04

+3

請參閱http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html以獲得關於該問題的更詳細解釋(以及相當長的具有不規則性的語言列表)。 – 2009-10-27 17:38:54

+0

謝謝帕維爾,我已經編輯了相應的問題 – zvolkov 2009-10-27 18:46:23

回答

11

NSLocalizedString將讀取應用程序包中的字符串表。因此,您需要支持的語言列表在編譯時已知。不必擔心如何編碼每種可能的語言,只需支持您所支持的語言。

如果您的翻譯來找你,並說,支持火星,你需要爲偶數和奇數單獨拼寫,你可以調整你的代碼,以這樣的:

if (objectList.count == 1) { 
    NSLocalizedString(@"ObjectCount1", @"display one"); 
} else if (objectList.count % 2 == 0) { 
    NSLocalizedString(@"ObjectCountEven", @"display even"); 
} else if (objectList.count % 2 == 0) { 
    NSLocalizedString(@"ObjectCountOdd", @"display odd"); 
} 

en.lproj /Localizable.strings:

ObjectCount1 = "1 object"; 
ObjectCountEven = "%d objects"; 
ObjectCountOdd = "%d objects"; // same as ObjectCountEven 

mars.lproj/Localizable.strings:

ObjectCount1 = "1 object-o"; 
ObjectCountEven = "%d object-e"; 
ObjectCountOdd = "%d object-o"; // same as ObjectCount1 

對不起,如果這聽起來不太理想,但人類語言雜亂無章,所以爲所有人尋找一個優雅,統一,通用的解決方案是浪費時間。沒有一個。

4

我剛剛發佈了JJPluralForm,這是對Mozilla的PluralForm的改編。

因此,您不必擔心所有if-else,switch-case代碼在您的代碼中進行本地化,隨着您的本地化數量的增長,這將變得無法維護。

[[JJPluralForm sharedManager] pluralStringForNumber:numberOfObjects 
            withPluralForms:NSLocalizedString(@"N_OBJECTS_PLURAL_STRING", @"") 
            localizeNumeral:YES]; 

每個本地化:

喜歡的東西,你給的例子可以與處理。字符串文件然後將N_OBJECTS_PLURAL_STRING本地化爲複數形式的分號分隔列表。對於英語,那將是"%@ object;%@ objects"

查看該項目瞭解更多詳情。

+0

哦,不錯,你處理阿拉伯語的雙重情況! – benzado 2012-07-23 04:09:20

3

Smartling發佈了一個開源框架來支持符合CLDR標準的複數形式。

https://github.com/Smartling/ios-i18n

要使用它,你在你的鑰匙跟隨CLDR風格標籤添加一個特殊標記,並呼籲SLPluralizedString代替NSLocalizedString。 。在運行時庫會選擇基於應用程序正在運行中的語言使用權串

那麼你的英語.strings文件將有:

"%@ apples##{one}" = "One apple"; 
"%@ apples##{other}" = "%@ apples"; 

俄羅斯.strings文件:

"%@ apples##{one}" = "%@ яблоко"; 
"%@ apples##{few}" = "%@ яблока"; 
"%@ apples##{many}" = "%@ яблок"; 
"%@ apples##{other}" = "%@ яблока"; 

和代碼來調用它可能看起來像:

NSString *s2 = [NSString stringWithFormat:SLPluralizedString(@"%@ apples", number, nil), number]; 

不e這個例子演示了這個庫的優點之一 - 它允許你使用表達式語言編寫你的原始字符串或翻譯,甚至可能不使用格式說明符。

在寫這篇文章時,我是Smartling的產品經理。

0

這個問題有更強大的解決方案。看看在Tr8n庫從TranslationExchange.com

https://github.com/tr8n/tr8n_objc_clientsdk

庫使用TranslationExchange的TML(翻譯標記語言),這使得國際化進程中非常容易。首先,您甚至不需要再次處理字符串XML文件,真的...... - Tr8n SDK將爲您即時創建和管理您的String文件 - 您將永遠不會再看到它們。

你的具體的例子,簡直是:

Tr8nLocalizedStringWithTokens(@"{count || object}", @{@"count": objectList.count}) 

Tr8n庫會自動選擇合適的複數形式爲您在任何語言。哈?是的,這是神奇的。上述令牌例子的完整形式其實是:

{count:number || one: object, other: objects} 

這意味着,「計數」令牌是映射到使用關鍵字「一」和「其他」英文複數數字類型的....但Tr8n很聰明,不會讓你輸入所有這些。將參數序列映射到適當的規則值也足夠聰明。當然,它知道「count」通過命名約定與數字規則相關聯。因此,簡單地變爲:

{count || object} 

順便說一句,因爲你已經提到俄羅斯,俄語翻譯爲上述只會是:

"{count || object}" = "{count || объект, объекта, объектов}" 

這個例子太簡單了,讓我們來看看一個更有趣的一個:

Tr8nLocalizedStringWithTokens(
    @"{user} uploaded {count || photo} to {user | his, her} photo album.", 
    @{@"user": user, @"count": 5} 
) 

首先,運氣好的話翻譯使用標準iOS國際化庫(或任何其他庫的這個問題)這句話......這是一個笑話 - 但實際上,有沒有辦法使用任何東西,但Tr8n。

上述TML的翻譯成俄文,簡直是:

@"{user || загрузил, загрузила} {count || фотографию, фотографии, фотографий} в свой фотоальбом." 

在這裏,我們處理性別統治我們處理數字的規則一樣。但是,不是「一個」,「少數」,「其他」,我們有「男性」,「女性」,「未知」 - 每種語言可能有不同的性別和數字規則。 Tr8n會處理它,所以你不必這樣做。

好吧,讓我們把它帶到下一個級別。你已經決定你必須有照片的數量要大膽。小菜一碟。

Tr8nLocalizedAttributedStringWithTokens(
    @"{user} uploaded [bold: {count || photo}] to {user | his, her} photo album.", 
    @{ 
    @"user": user, 
    @"count": 5, 
    @"bold": @{@"font":@{@"name": @"system", @"size": @12, @"type": @"bold"}} 
    } 
) 

[bold:...]是一個裝飾標記。你有沒有注意到我們將宏切換到了AttributedString版本?這個宏實際上會使用iOS的原生裝飾機制產生一個NSAttributedString。你能猜出俄文的翻譯是什麼嗎?

@"{user || загрузил, загрузила} [bold: {count || фотографию, фотографии, фотографий}] в свой фотоальбом." 

順便說一句,你可以在其他地方預先定義自己的所有裝飾記號,這樣你就不必保持每次都定義它們。

讓我們做只是多了一個最後的例子......再說了,你有以下形式的新聞源故事:

Tr8nLocalizedAttributedStringWithTokens(
    @"{actor} sent {target} [bold: {count || gift}].", 
    @{ 
    @"actor": user1, 
    @"target": user2, 
    @"count": 5 
    } 
) 

它不會在英文看起來有趣。但它以俄語或任何其他語言支持語言案例。 {target}的名稱,如果它恰好是俄文,實際上需要使用俄語Dative Language Case。

http://en.wikipedia.org/wiki/Dative_case

如果你不會說俄語,你也許並不需要了解它。但你的俄語翻譯應該。讓我們來看看俄羅斯翻譯,那麼:

@"{actor || подарил, подарила} {target::dat} [bold: {count || подарок, подарка, подарков}].", 

Tr8n是足夠聰明,利用其強大的語言規則引擎,並與格語言的情況下適用於通過使用{target}令牌傳遞的俄文名字......

那對於一個簡單的數字問題來說有點長。感謝您閱讀這一點。希望能幫助到你。

聲明:我是Tr8n框架和TML語言的創建者。如果您有任何問題,請平郵我,我很樂意幫助您解決所有翻譯問題。

2

順便說一下,從iOS 7和Mac OS X 10.9開始,本地化中內置了對複數形式的支持。從16:10開始,請參閱WWDC 2013 video「讓您的應用程序適應全球」。複數是局部的.stringsdict plist文件,然後你只是做

NSLog(@"%@", [NSString localizedStringWithFormat: 
      NSLocalizedString(@"%d objects", @"display multiple objects"), n]); 
相關問題