將標題取名爲國際化及本地化(internationalization and localization),是由於這兩個概念是有差別的,而這個差別經常被咱們忽略,如下是維基百科的解釋:html
國際化是指在設計軟件,將軟件與特定語言及地區脫鉤的過程。當軟件被移植到不一樣的語言及地區時,軟件自己不用作內部工程上的改變或修正。本地化則是指當移植軟件時,加上與特定區域設置有關的信息和翻譯文件的過程。json
國際化和本地化之間的區別雖然微妙,但卻很重要。國際化意味着產品有適用於任何地方的「潛力」;本地化則是爲了更適合於「特定」地方的使用,而另外增添的特點。用一項產品來講,國際化只需作一次,但本地化則要針對不一樣的區域各作一次。這二者之間是互補的,而且二者合起來才能讓一個系統適用於各地。xcode
有些時候咱們也會用國際化或者全球化代替這二者含義。安全
做爲一款優秀的產品咱們作多語言版本時不該僅僅考慮到翻譯這一層面,還有更多本地化相關內容須要咱們注意,這篇文章主要涉及的也是本地化這一塊。app
本篇文章主要介紹Internationalize和Test這兩步。dom
本文目錄爲:ide
1.增長多語言佈局
2.UI元素的本地化post
3.資源文件本地化測試
4.字符串相關的本地化
5.使用NSLocal進行本地化
6.從右到左語言的處理
7.本地化測試
一、在項目導航欄選擇項目(不是target)
二、在Localizations一欄,點擊「+」號,添加語言
Chinese(Simplified)(zh-Hans)
,
Japanese(ja)
至此咱們的項目就開啓了對應語言的本地化支持。
三、在對話框中選中你想本地化的文件。
一、語言設置:Setting -> General -> Language & Region
對於sotryboard
和xib
文件的本地化是Xcode直接支持的。 在添加語言時會提示咱們自動選擇建立本地化文件,若是是在添加語言以後建立的IB文件,能夠經過xcode右側屬性欄中點擊Localize...
生成本地化文件。
一、方法一 對於圖片內容咱們能夠經過同IB文件的方式進行本地化,可是有一個限制就是圖片要是放到項目文件層級的,而不能放到Assets文件夾中。 好消息是Xcode 11將放開這種限制,對於Assets引入的圖片也能夠作本地化處理。
二、方法二 除了Xcode自己支持的方式,咱們還能夠經過命名來區分圖片內容,把圖片名當作須要本地化的字符串,各個語言對應不一樣版本的圖片名,這樣也能夠實現圖片文件的本地化。
若是是內置的像是音視頻,json或者其餘類型的配置文件這類內容,可使用圖片文件的方法二進行引入。
更多詳細的設置能夠參考這個文章:iOS語言國際化/本地化-實踐總結
Auto layout
是相對佈局,它有能力在語言和區域變化時進行自適應。如下有幾點使用auto layout的技巧:
一、移除寬度的約束 相同含義下不一樣語言寬度每每不同,應該讓控件可以自適應。
二、使用內容內部大小 fields和label默認是自動調整大小的,若是一個顯示本地化內容的視圖須要這個功能,選擇該view,選擇Editor > Size To Fit Content
三、使用leading
和trailing
屬性 正常leading
和trailing
對應left
和right
,他們含義相同。可是有些國家,像是希伯來和阿拉伯的人使用習慣是從右往左。若是你是使用leading
和trailing
,在該環境下將自動對應right
和left
。
四、將視圖固定到相鄰視圖 就是定義相鄰約束,避免某一視圖變化致使重疊。
這個功能只支持使用storyboard
和xib
進行佈局的UI。 一、選中須要測試的.storyboard或者.xib文件 二、選擇菜單欄 View > Assistant Editor > Show Assistant Editor
對於全部面向用戶的字符串都要使用NSString, NSAttributedString
,對於Swift就是String, AttributedString
,由於他們支持Unicode,Unicode是世界上全部書寫系統的字符編碼標準。
對於一些特殊的字符串需求: 一、訪問字符串中的字符 使用NSString中的rangeOfComposedCharacterSequenceAtIndex:
和 rangeOfComposedCharacterSequencesForRange:
方法,他們會確保你在取字符串時不會破壞原文本。看一個例子你可能會明白:
二、遍歷字符串
若是咱們要遍歷展現下面的字符串:
能夠經過enumerateSubstringsInRange:options:usingBlock:
方法,其中options參數若是傳遞NSStringEnumerationByComposedCharacterSequences
將會按照最小字符進行遍歷,若是選用NSStringEnumerationByWords
將會按照詞語進行遍歷。 以上例子使用該值遍歷的結果是:
更多關於字符串相關的本地化問題能夠參照該條視頻: WWDC 2013 Making Your App World-Ready
三、關於人名,郵寄地址,電話號碼的檢測 由於不一樣國家對於人名和電話號碼的規則差異較大,咱們能夠針對不一樣國家寫正則進行檢測,也可使用蘋果提供的一個特殊含義字符的檢測類:NSDataDetector
支持檢測的類型包括日期,地址,連接,手機號,交通訊息。
將語言設置爲English(United Kingdom),區域設置成United States,經過如下API獲取到:
//en
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
複製代碼
通常獲取語言所用的方式是經過Bundle也就是第一種方式。
NSLocale對象封裝關於特定區域格式化標準的信息,包括日期,時間,測量,數字,貨幣等一系列內容。
將語言設置爲English(United Kingdom),區域設置成United States,經過如下API獲取到:
//en-GB_US
[NSLocale currentLocale].localeIdentifier;
//en
[NSLocale currentLocale].languageCode;
複製代碼
其中languageCode跟經過Bundle獲取到的是同樣的。
其中localIdentifier表示爲en-GB_US
,對應爲:語言id-國家id_區域碼
,這幾個內容均可以經過NSLocal對象取到。
由於每種語言對於引號的使用是不同的,咱們能夠經過NSLocal獲取到引號
//1.Get the language that the app is using.
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
//2.Get the associated locale object.
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
//3.Get the beginning and ending symbols for quotes from the locale object.
bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];
eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
//4.Format a string using the locale-sensitive quotes.
quotedString = [NSString stringWithFormat:@"%@%@%@", bQuote, myText, eQuote];
複製代碼
如下展現了不一樣區域對於myText
爲@"iPhone"
時的字符串效果。
一、建立格式化字符串 應該使用localizedStringWithFormat:
而不是stringWithFormat:
。
NSString *localizedString = [NSString localizedStringWithFormat:@"%3.2f", myNumber];
複製代碼
此方法會根據系統Local進行顯示。
二、日期和時間轉字符串 使用NSDateFormatter
表示NSDate
對象。推薦使用這個方法:localizedStringFromDate:dateStyle:timeStyle:
。
//14 Aug 2019 at 11:19
NSString *localizedDateTime = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterShortStyle];
複製代碼
下表展現了語言爲英語,區域是美國時的日期和時間格式:
dateStyle
爲
NSDateFormatterMediumStyle
,
timeStyle
爲
NSDateFormatterShortStyle
在不一樣語言和地區時的表現形式:
//1.Create an NSDateFormatter object.
NSDateFormatter *dateFormatter = [NSDateFormatter new];
//2.get a localized format string from a template that you provide.
NSString *localeFormatString = [NSDateFormatter dateFormatFromTemplate:@"MMM d" options:0 locale:dateFormatter.locale];
//3.Set the format of the NSDateFormatter instance to the locale-sensitive format string.
dateFormatter.dateFormat = localeFormatString;
//4.Use the stringFromDate: method to get a localized string representation of the date.
NSString *localizedString = [dateFormatter stringFromDate:[NSDate date]];
複製代碼
在不一樣語言和區域下localizedString
對應的內容爲:
三、解析日期字符串
//1.Create a date formatter object.
NSDateFormatter *dateFormatter = [NSDateFormatter new];
//2.Set the formatter’s style to a preset style.
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
//3.If the input string is not expected to contain a time, set the time style to none.
dateFormatter.timeStyle = NSDateFormatterNoStyle;
//4.Set the leniency to YES (enables the heuristics).
dateFormatter.lenient = YES;
//5.Convert the string to a date object.
NSDate *date = [dateFormatter dateFromString:inputString];
複製代碼
咱們輸入的字符串是9/3/14
,dateStyle設爲NSDateFormatterShortStyle
,若是區域爲美國,咱們獲得的NSDate信息爲:2014-09-03 07:00:00 +0000
,若是區域爲德國,咱們將獲得2014-03-09 08:00:00 +0000
。
本地化設置會影響小數點符號,千分符,貨幣符等內容,好比數字1,234.56
在乎大利應該表示爲1.234,56
,因此對於數字的格式化咱們應該用NSNumberFormatter
處理。 注意:NSNumberFormatter不是現成安全的 一、將Number轉成本地化的字符串 可使用NSNumberFormatter
的localizedStringFromNumber:numberStyle:
方式
NSString *localizedString = [NSNumberFormatter localizedStringFromNumber:myNumber numberStyle:NSNumberFormatterDecimalStyle];
複製代碼
如下是不一樣語言和區域關於數字的顯示效果,左側的style及numberStyle
:
//1.Create a number formatter object.
NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
//2.Set the formatter’s style to a preset style.
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
//3.Set the leniency to YES (enables the heuristics).
numberFormatter.lenient = YES;
//4.Convert the string to a number object.
NSNumber *number = [numberFormatter numberFromString:inputString];
複製代碼
三、經過NSCalendar計算日期 NSCalendar類封裝了日曆的全部區域差別和複雜性。說他具備複雜性是由於在不一樣國家,一年之中的月份多是12或者13,一月中的天數多是5到31的任意值,每週第一天多是週六,週日或者週一。能夠看下錶
//1.Create an NSDateComponents object.
NSDateComponents *components = [[NSCalendar currentCalendar]
components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSEraCalendarUnit
fromDate:[NSDate date]];
//2.Access the values for day, month, year, and era.
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSInteger era = [components era];
複製代碼
四、監聽本地化信息或者時區修改 能夠經過NSCurrentLocaleDidChangeNotification
監聽區域的改變
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localeDidChange:) name:NSCurrentLocaleDidChangeNotification object:nil];
複製代碼
一樣的監聽時區變化能夠經過NSSystemTimeZoneDidChangeNotification
。
支持從右到左向的語言,在約束層面應該使用Auto layout中的leading
和trailing
屬性,而不是right
和right
。能夠經過如下對比看到區別
若是咱們想獲取當前語言是否應該是從右到左項的語言能夠經過如下方法:
//right-to-left language
if ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:view.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft) {
…
}
複製代碼
在iOS中默認的文本對齊方式是「natural」,在OS X中默認方式是「left」。natural的含義就是會感受語言的方向自動調整爲left或者right。 若是你想NSMutableParagraphStyle
對象的對齊方式爲天然的方向,能夠:
[[(NSMutableParagraphStyle *)paraStyle setAlignment:NSNaturalTextAlignment];
複製代碼
雙向文本就是一段文本中及含有從右往左的文本還含有從左往右的文本。是否是感受很詫異?由於即便像阿拉伯和希伯來國家這些書寫習慣爲從右往左,可是對於數字和拉丁文是從左往右寫的。若是你使用的是標準控件,像Label,TextView,Textfiled他們會自動處理雙向文本內容。若是你是使用自定義控件,那這些問題就須要你手動處理。
在某些特殊的時候,系統默認的行爲可能會致使一些不正確的結果,這時咱們能夠經過添加Unicode標記進行糾正。
例如,手機號在全部語言中都是從左往右讀的,若是一個須要本地化的字符串變量表示一個手機號,若是咱們須要保證他是從左往右的順序展現,須要再字符串首部增長一個從左往右的嵌入字符(LRE):U+202A
,在字符尾部增長定向格式字符(PDF):U+202C
。
// Wrap the plus (+) prefix and phone number in left-to-right directional markers
NSString *phoneNumber = @"408-555-1212";
NSString *localizedPhoneNumber = [NSString stringWithFormat:@"\u202A%@\u202C", phoneNumber];
複製代碼
有些視圖是不該該翻轉的,在iOS9以後能夠經過UIView的semanticContentAttribute
屬性手動指定視圖應該是從左到後仍是從右往左的方式展現。
若是是想翻轉圖片能夠經過UIImage
的imageFlippedForRightToLeftLayoutDirection
方法。
這個功能只能在.storyboard和.xib文件實現。
經過Edit Schema > Run > Options
而後點開語言選項,除了各類系統支持語言外,翻到最下面能夠看到這幾個選項。
2.Right-to-Left Pseudolanguage 將語言方向改爲從右往左,也能夠將語言改爲阿拉伯文或者希伯來文。
3.Accented Pseudolanguage 帶重音符號。
4.Bounded String Pseudolanguage 帶邊界的字符串。
5.Right-to-Left Pseudolanguage With Right-to-Left Strings 同從右往左語言。