了解Cocoa用戶界面中字符串代碼使用
了解Cocoa用戶界面中字符串代碼使用方法是本文要介紹的內(nèi)容,iOS的界面前臺(tái)的展示,有字符和圖像都是通過(guò)編碼來(lái)實(shí)現(xiàn)的,新的Cocoa的開(kāi)發(fā)者應(yīng)該通過(guò)多看蘋(píng)果開(kāi)發(fā)文檔,熟悉函數(shù)及各個(gè)事件靈活的使用方法,就能快速提高自己的iOS開(kāi)發(fā)的技能.
在這篇文章中,我將提到在iPhone用戶界面上管理和使用的文本字符串的最好程序. 這是一個(gè)相當(dāng)簡(jiǎn)單的技術(shù)主題,但是Cocoa建立作為處理用戶界面的字符串的最好的程序例子,新的Cocoa的開(kāi)發(fā)者應(yīng)該會(huì)注意到這點(diǎn).由于它不可避免會(huì)提及,我也提到在你的應(yīng)用程序使用字符的步驟,但請(qǐng)記?。耗銘?yīng)該按好的程序來(lái)練習(xí)字符串處理技能,盡管你沒(méi)有打算調(diào)整你的應(yīng)用程序.
- Introduction (the wrong way)
簡(jiǎn)述(錯(cuò)誤的方法)
在一定的技術(shù)水平下給用戶的界面添加文字字符串并不是難事.在源代碼里面填充代碼就像添加文字一樣簡(jiǎn)單.
可能就是一個(gè)
UI標(biāo)簽
實(shí)現(xiàn)字符的
這段代碼是iOS的UI的標(biāo)簽代碼
在Mac OS X,你應(yīng)該設(shè)置為
stingValue的屬性
可能是一個(gè)
NSTexField的屬性
另外的這個(gè)步驟是一樣的.
雖然這個(gè)可以實(shí)現(xiàn)功能,但你你不應(yīng)該用這種方法來(lái)設(shè)置用戶界面的字符串.
B---用字面字符串設(shè)置標(biāo)簽(正確的方法)
最完整的把字符添加到你的Cocoa應(yīng)用程序的用戶界面是如下的方法:
- someUserInterfaceLabel.text =
- NSLocalizedStringFromTable(
- @"Text to display", // the native language string
- @"SomePageLabels", // the category
- @"Label display string"); // a comment describing context
這個(gè)是相當(dāng)?shù)姆彪s的.它也可以如下的用法:
- someUserInterfaceLabel.text = NSLocalizedString(@"Text to display", nil);
如果你沒(méi)有做其它的步驟,這個(gè)代碼也會(huì)產(chǎn)生同樣錯(cuò)誤.
你可以
一直使用這個(gè)(NSLocalizedString)
每個(gè)用戶界面的宏程序都有字符串在你的代碼中
但是這個(gè)有點(diǎn)不一樣
NSLocalizedString這樣的代碼需要很多的輸入,除非你已經(jīng)做了另外更多的步驟并且程序不需要什么不同的功能?如果我現(xiàn)在不考慮轉(zhuǎn)換我的程序,它們是不是完全無(wú)用的呢?
為什么NSLocaliedString是重要的,盡管你不想來(lái)使用
明顯地,
- NSLocalizedString
- [...] functions (and the less common
- [...]功能(比通常
- CFCopyLocalizedString
- CFCopylocalizedString
[...] 變體的值是讓所有的個(gè)功能本地話語(yǔ)言(i.e 讓你的程序顯示為不同的語(yǔ)言)
從技術(shù)上說(shuō),他們甚至不是一種功能——它們只是宏程序的請(qǐng)求
- -[NSBundle localizedStringForKey:value:table:]
- -[NSBundle localizedStringForKey:value:table:]
方法-你可以用宏程序,并且因?yàn)楹芏嗟睦碛赡悴挥谜{(diào)用什么方法.我會(huì)在下部分來(lái)討論語(yǔ)言變換的機(jī)制.
然而,盡管你不想讓你的程序可以顯示更多的語(yǔ)言,你也得使用NSLocalizedString
一直用NSLocalizedString這有幾個(gè)理由:
1.未來(lái)改變的基礎(chǔ) :NSLocalizedString
2.模型視圖控制設(shè)計(jì)模式:它保持了你的模型層/表示層的詳細(xì)記錄,其中至少有一個(gè)不正確的地位從你的控制器源碼里面撤出.在某種情況下,你可以簡(jiǎn)單的該表.strings的文件來(lái)為你的程序更新來(lái)調(diào)整用戶的界面,而不用單獨(dú)去修改代碼
3.關(guān)注點(diǎn)分離:它清晰地顯示了在用戶表示層字符串,作為對(duì)應(yīng)字符只供編程使用的.
4.優(yōu)化冗繁的程序:從你的控制器獨(dú)立用戶界面字符,你不會(huì)愿意從用戶界面去返回去閱讀字符串,或者程序員已經(jīng)放置好在用戶界面上面的放好的字符
未來(lái)是很難預(yù)測(cè)的.你不知道你在以后會(huì)想把轉(zhuǎn)化成別的語(yǔ)言.到時(shí)候你要通過(guò)你的全部的代碼和找出有所有的字符串的目錄是很費(fèi)時(shí)間,而且會(huì)導(dǎo)致錯(cuò)誤.相反得,應(yīng)該把所有的事情通過(guò)使用NSLocalizedString來(lái)轉(zhuǎn)化的語(yǔ)言的習(xí)慣.
這很容易實(shí)現(xiàn),甚至當(dāng)你在解碼的時(shí)候,你就能使用它了.
分離關(guān)注點(diǎn)
分離關(guān)注點(diǎn)在瀏覽代碼是很有用,并且可以知道動(dòng)向.考慮下面單獨(dú)的代碼段
- [someDictionary setObject:@"value" forKey:SomeKeyNameString];
- [someDictionary setObject:NSLocalizedString(@"value", nil) forKey:SomeOtherKeyNameString];
不用知道
什么是someDictionary屬性
或者是someKeyNameString和SomeOtherkeyName的作用是什么
- SomeKeyNameString
- and
- SomeOtherKeyNameString
屬性的含義是,我們知道第二個(gè)字符串的是用來(lái)在第一個(gè)字符串不能直接實(shí)現(xiàn)的一個(gè)值來(lái)表現(xiàn)用戶界面的.
這個(gè)獨(dú)立使用的這個(gè)屬性,對(duì)用戶界面的顯示是很有幫助的,相對(duì)someKeyNameString,它在程序當(dāng)中有更多的用法.
- Discourages other bad practices
優(yōu)化冗繁的代碼
如果你認(rèn)為NSLocalizedString就像它們的輸出是個(gè)黑盒子,這個(gè)可以幫助你在管理用戶界面的元素的時(shí)候避免極差的控制器的設(shè)計(jì).它可以作為一個(gè)概念的工具,讓你通過(guò)有效的方法來(lái)設(shè)計(jì),不是以個(gè)愚蠢的設(shè)計(jì).
你的控制器代碼會(huì)把用戶界面的字符串當(dāng)作可以被寫(xiě),但是不會(huì)被讀.從你的用戶界面閱讀基本的字符串是很不好受.
在上面的分離關(guān)注點(diǎn)的那個(gè)例子中,你可以能會(huì)認(rèn)為SomeKeyNameString和SomeOtherKeyNameString
是在這個(gè)例子中被定義為全局變量,就是你可以用來(lái)定義本地語(yǔ)言的一個(gè)變量.在多數(shù)情況下,使用國(guó)際化的變量的并不好.
我們?cè)谌肿兞恐卸x了字典的鍵,因?yàn)橛袀€(gè)程序的不同的位置需要使用同樣的屬性,在多處信息交換的時(shí)候就會(huì)出現(xiàn)錯(cuò)誤.在用戶界面的字符串的值,你不應(yīng)該有另外的變量需要和其中的另一個(gè)完全一樣的值:你不應(yīng)該從你的用戶界面去回讀代碼或者與用戶界面的協(xié)助.一般來(lái)說(shuō),如果的相同的用戶界面需要多次使用,才可以有同樣字符串在程序里面.(例如.你在繪制同樣的對(duì)象),但是在這種的情況下,代碼都是公用的,而這個(gè)字符串也只能在代碼中出現(xiàn)一次.
如果您需要唯一標(biāo)識(shí)標(biāo)簽或文本顯示的類型,測(cè)試它所包含的文本是錯(cuò)誤的方法.一個(gè)更好的方法是使用UIView的標(biāo)簽 /NSActionCell
tag
- value of any
- UIView
- /
- NSActionCell
- and then map the
然后描述對(duì)象的角色和功能的屬性值
tag
- value onto the object's role or function (
tag它是一個(gè)指針的值,所以你可以存儲(chǔ)非保留對(duì)象,而不僅僅是整數(shù).
標(biāo)簽的屬性值不保存任何的其它的值,它是由控制器它是由控制器來(lái)跟蹤用戶界面項(xiàng)目和它們的狀態(tài)。
轉(zhuǎn)化的過(guò)程
最終,你可能要翻譯你的外文的程序.讓我們看看所涉及的步驟.
建立你的.strings的文件
你的程序包含的“.strings"的文件是你所需要翻譯的,在默認(rèn)的情況下,不會(huì)有任何”.strings“的文件(除了InfoPlist.strings文件,該文件是為翻譯您的Info.plist文件中的字符串)
第一步是確保你有一個(gè)指定的目錄(可能是你項(xiàng)目文件夾資源子目錄).如果是在處理的英文的字符才一個(gè)指定的目錄應(yīng)該命名為"en.lproj",否則你應(yīng)該用ISO639-1和ISO639-2 替代”en“的標(biāo)記.如果需要的話,你可以可以使用腳本和區(qū)域標(biāo)識(shí)符作為描述蘋(píng)果的開(kāi)發(fā)的語(yǔ)言和區(qū)域標(biāo)識(shí)符.
一個(gè)文件夾名稱的備注:這是很容易見(jiàn)到用“English.Ipoj”代替“en.Iproj”,事實(shí)上,如果你獲取文件的信息并且選擇了生成本地化文件,Xcode3就會(huì)自動(dòng)生成用這個(gè)名字生成的那個(gè)名字的文件夾.蘋(píng)果公司表示這些命名已經(jīng)老了,從MacOSX 10.4以上的版本就傾向于ISO639-1和ISO639-2代號(hào).不要使用舊的“English.proj”類型的名字,用“en.lproj”來(lái)替代,如果是自動(dòng)創(chuàng)建的(是的,如果你改了文件夾的名字需要更新的你Xcode的路徑)
現(xiàn)在我們?cè)诔绦蚶锩?,我們能從NSLocalizedString函數(shù)自動(dòng)創(chuàng)建“.strings”文件
NSLocalizedString實(shí)現(xiàn)這個(gè)功能,他開(kāi)你的項(xiàng)目的根目錄運(yùn)行終端,然后輸入下面的命令:
- find -E . -iregex '.*\.(m|h|mm)$' -print0 | xargs -0 genstrings -a -o Resources/en.lproj
- find -E . -iregex '.*\.(m|h|mm)$' -print0 | xargs -0 genstrings -a -o Resources/en.lproj
這些命令會(huì)處理你的程序目錄層次結(jié)構(gòu)的的所有.m .h .mm的文件和在en.lpoj中創(chuàng)建“.strings”文件(注意,en.lproj的目錄必須是已經(jīng)存在) 這是假定你創(chuàng)建本地化資源目錄位于“資源/ en.proj“,相對(duì)于你的項(xiàng)目的根目錄,很明顯,你需要改變這目錄位置,如果你把它放在別處。
“.strings”的代碼可能會(huì)有很多的條目就像下面的代碼:
- "Some UI string %@ to translate %@" = "Some UI string %1$@ to translate %2$@";
- "Some UI string %@ to translate %@" = "Some UI string %1$@ to translate %2$@";
你的程序翻譯功能僅需要對(duì)應(yīng)翻印同樣的描述就可以.注意你的字符串的占位符已經(jīng)給出的次序,這樣可以是轉(zhuǎn)換的時(shí)候改換原來(lái)的占位符,如果如果你使用占位符,您應(yīng)該包括注釋,解釋他們要去秩序.
本土化與國(guó)際化:
1.國(guó)際版本:你從原來(lái)的程序轉(zhuǎn)化過(guò)來(lái)的
2.原始版本:你翻譯程序和轉(zhuǎn)化新的版本
通過(guò)那個(gè)幾個(gè)術(shù)語(yǔ),NSLocalizedString的作用
創(chuàng)建和打包“.strings”的文件是國(guó)際化的窗口.
一般來(lái)說(shuō),創(chuàng)建新的語(yǔ)言的轉(zhuǎn)化版被稱為本地化的過(guò)程.實(shí)際上,它包括了兩個(gè)步驟:
genstrings只能處理靜態(tài)NSLocalizedString和CFCopyLocalizedString字符串
可以被自動(dòng)提取的字符是在NSlocalizedString函數(shù)里面的:
- NSLocalizedString
- [...] and
- CFCopyLocalizedString
[...]宏指令顯然,所有的用戶界面文本需要被包含到上面的函數(shù)(CFCopyLocalizedString),也得記住底層的樣子
- [NSBundle localizedStringForKey:value:table:]
的方法是不會(huì)自動(dòng)被處理的
為什么你會(huì)直接用-[NSBundle localizedStringForKey:value:table:]?它的原因是他會(huì)自動(dòng)生成所需的字符串.
如果程序檢測(cè)到在本地化的宏程序中有其它的靜態(tài)的字符串,這個(gè)genstrings的命令就會(huì)出現(xiàn)錯(cuò)誤. 這是恰當(dāng)?shù)?,因?yàn)槟悴幌M愕淖兞棵晦D(zhuǎn)化和函數(shù)調(diào)用(它們只需要轉(zhuǎn)化這些調(diào)用的結(jié)果)。
你會(huì)使用-[NSBundle localizedStringForKey:value:table:]的原因是:那些被轉(zhuǎn)化成本地語(yǔ)言的字符串是那些在代碼里面的(或在一個(gè)文件不是從代碼生成的“.string “),你只需要去尋找它們的變化。
編碼的問(wèn)題
從Mac OS X10.5開(kāi)始,你可以把任何UTF- 8字符在你的NSLocalizedString函數(shù)。在這之前, 他們必須是用Unicode轉(zhuǎn)義\\ Uxxxx風(fēng)格的純粹的7位的ASCII碼的另外方式或者你可以使用帶- macRoman命令行選項(xiàng)MacRoman使用MacRoman高ASCII字符。
小結(jié):了解Cocoa用戶界面中字符串代碼使用方法的內(nèi)容介紹完了,希望本文對(duì)你有所幫助!