2012-08-30 86 views
28

我似乎有些應用程序可以在應用程序內部更改語言,而無需重新啓動應用程序,我想知道它們是如何實現的。在iOS中更改應用程序語言而無需重新啓動應用程序

例如,我們使用NSLocalizedString的,我知道這是可能在main.m設置在運行時的語言時,未初始化的AppDelegate,但一旦它被初始化(尤其是你的視圖控制器創建),改變它並沒有有效,直到下重啓

[[NSUserDefaults standardUserDefaults] 
    setObject:[NSMutableArray arrayWithObjects:language, nil] 
    forKey:@"AppleLanguages"]; 

任何人有任何想法如何將這些動態語言的變化而不需要重新啓動應用程序來完成?

+0

如何刪除窗口並像'application:didFinishLaunchingWithOptions:'中一樣重建接口。沒有嘗試過自己,但也許這個作品 – 2012-09-01 10:46:10

+1

評論[這個鏈接] [1]可能會幫助你。 [1]:http://stackoverflow.com/questions/1576904/how-to-change-iphone-app-language-during-runtime –

+0

[此酮](HTTP的可能重複:// stackoverflow.com/questions/11578298/change-application-language-setting-in-ios-not-the-whole-device/11578590#11578590)。另外,我在那裏發佈了一個簡單的答案。 您可以爲每種語言創建一個包含所有必需字符串的文檔,並從中加載它們。 –

回答

1

我總是使用這種方式,它完美的工作,它可能會幫助你。


你應該將所有的文本與NSLocalizableString(...)UI當前語言在你的每一個UIViewController-viewWillAppear:方法。

使用這種方式,你(我的意思是,用戶)不需要改變iOS設置語言後重新啓動應用。


當然,我正在使用蘋果的標準本地化架構。

上(2013年10月24日)更新

我所經歷的–viewWillAppear:方法不適用於當應用程序進入到前景的實際視圖中執行;爲了解決這個問題,當我在視圖中收到UIApplicationWillEnterForegroundNotification通知時,我也會執行該過程(請參見上文)。

+0

你如何改變語言? – Dejell

+0

在_Settings_應用程序中:_General_ - > _International_ - > _Language_,如果您的應用程序支持所選語言,當您切換回您的應用程序時,它將以使用新語言顯示;你可以在你的應用程序中繼續之前開始的會話。 – holex

+5

但這並沒有回答這個問題怎麼做明智的方案 – Dejell

5

還有其他方法進行一些討論在這裏,特別是通知爲基礎的方法:

iOS: How to change app language programmatically WITHOUT restarting the app?

在我看來真的有三個任務在這裏: (1)資源進行重新定位,從自動加載碎粒。 (例如,如果您從一個筆尖動態實例化另一個自定義UIView,則仍會加載「舊」語言字符串和設置(圖像,文本方向)。(2)重新定位當前顯示在屏幕上的字符串。 (3)開發人員(您)插入的字符串在程序代碼中的重新定位。

讓我們從(3)開始。如果你尋找定義,你會注意到NSLocalizedString是一個宏。因此,如果您不想過多地更改現有代碼,則可以通過創建新的頭文件來解決(3)的問題。在該頭文件中,#undef然後再#define NSLocalizedString從適當的地方選取本地化的字符串 - 不是iOS默認的字符串,而是您在某個全局變量中記錄的字符串(例如,在應用程序委託ivar中) 。如果你不想重新定義NSLocalizedString,但你仍然可以自己選擇,如果你不想讓未來的開發者不小心地調用它,而不是你用它來代替宏,你應該仍然可以使用#undef NSLocalizedString。不是一個理想的解決方案,但也許是最實用的。對於(1),如果你還沒有在Interface Builder中完成你的本地化,而是你在viewDidLoad等中動態執行它,那麼沒問題。你可以使用剛討論過的相同的行爲(即修改過的NSLocalizedString等)。否則,您可以(a)實現上述鏈接中描述的通知系統(複雜),或者(b)考慮將本地化從IB移動到viewDidLoad,或者(c)嘗試覆蓋initWithNibName:並將加載了舊語言的對象資源,一個加載了新的語言資源。穆罕默德在本次討論的最底部提到了這種方法:http://learning-ios.blogspot.ca/2011/04/advance-localization-in-ios-apps.html。他聲稱它會導致問題(viewDidLoad未被調用)。即使它不起作用,嘗試它也可能會使你指向某些事情。最後,(2)大概是最簡單的任務:只需刪除並重新添加當前視圖(或者在某些情況下,只需重新繪製它即可)。

0

我被卡在同一個問題,我的要求是「用戶可以選擇從下拉&應用程序語言已經根據所選語言(英語或阿拉伯語)的工作」我做了什麼我創建兩個XIB並根據XIB和文本取選定的語言。這樣用戶可以選擇語言。我用同樣的NSBundle。像

對於廈門國際銀行

self.homeScreen = [[HomeScreen alloc] initWithNibName:@"HomeScreen" bundle:[CommonData sharedCommonData].languageBundle]; 

對於文本

_lblHeading.text = [self languageSelectedStringForKey:@"ViewHeadingInfo"]; 

/** 
This method is responsible for selecting language bundle according to user's selection. 
@param: the string which is to be converted in selected language. 
@return: the converted string. 
@throws: 
*/ 

-(NSString*) languageSelectedStringForKey:(NSString*) key 

{ 

    NSString* str=[[CommonData sharedCommonData].languageBundle localizedStringForKey:key value:@"" table:nil]; 

    return str; 

} 
2

的想法是寫一個新的宏像NSLocalizedString,應檢查是否從另一個特定的捆綁或不帶翻譯。

方法2this article解釋如何做到這一點。 在這種特殊情況下,作者不使用新宏,而是直接[NSBundle mainBundle]設置了自定義類

我希望@holex能理解這個問題。

-1

你需要下載一次像這樣的包(其中@「恩」可能是語言環境需要):

NSString *path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"]; 
NSBundle *languageBundle = [NSBundle bundleWithPath:path]; 

,使宏/功能像NSLocalizedString其使用上包您加載束或使用方法直接像這樣

[languageBundle localizedStringForKey:key value:value table:tableName]; 

[[NSBundle mainBundle] localizations]列出了所有的應用程序本地化(包括「基地」)。

另外我寫了helper class這樣做(注意它有ReactiveCocoa作爲依賴)。它允許在不重新啓動應用程序的情況下更改語言,並在每次更改時發送當前語言環境

+0

不知道如何提高其他答案。 – Popeye

+0

那麼,它並不需要將undefined NSLocalizedString作爲最有幫助的答案,它概述瞭如何做到這一點,它不需要重新啓動應用程序,並且不會對審閱造成任何問題,並且對感興趣的代碼有示例代碼(包括免責聲明) 。如果你有建議如何改進它 - 我想看到它們並改進答案。 –

+0

我還沒有看到你的回答如何改善已經說過的話。在回答已經提供了答案的舊問題時,您需要說明爲什麼您可能是更好的方式來做到這一點,並分享代碼,而不僅僅是鏈接到代碼,因爲鏈接到期。 – Popeye

0

我的實現使用一個類來改變語言並訪問當前的語言包。這是一個例子,所以如果你要使用不同的語言,那麼就改變使用你的確切語言代碼的方法。

該類將從NSLocale中訪問首選語言,並獲取第一個使用該語言的對象。

@implementation OSLocalization 

+ (NSBundle *)currentLanguageBundle 
{ 
    // Default language incase an unsupported language is found 
    NSString *language = @"en"; 

    if ([NSLocale preferredLanguages].count) { 
     // Check first object to be of type "en","es" etc 
     // Codes seen by my eyes: "en-US","en","es-US","es" etc 

     NSString *letterCode = [[NSLocale preferredLanguages] objectAtIndex:0]; 

     if ([letterCode rangeOfString:@"en"].location != NSNotFound) { 
      // English 
      language = @"en"; 
     } else if ([letterCode rangeOfString:@"es"].location != NSNotFound) { 
      // Spanish 
      language = @"es"; 
     } else if ([letterCode rangeOfString:@"fr"].location != NSNotFound) { 
      // French 
      language = @"fr"; 
     } // Add more if needed 
    } 

    return [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]]; 
} 

/// Check if preferred language is English 
+ (BOOL)isCurrentLanguageEnglish 
{ 
    if (![NSLocale preferredLanguages].count) { 
     // Just incase check for no items in array 
     return YES; 
    } 

    if ([[[NSLocale preferredLanguages] objectAtIndex:0] rangeOfString:@"en"].location == NSNotFound) { 
     // No letter code for english found 
     return NO; 
    } else { 
     // Tis English 
     return YES; 
    } 
} 

/* Swap language between English & Spanish 
* Could send a string argument to directly pass the new language 
*/ 
+ (void)changeCurrentLanguage 
{ 
    if ([self isCurrentLanguageEnglish]) { 
     [[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"]; 
    } else { 
     [[NSUserDefaults standardUserDefaults] setObject:@[@"en"] forKey:@"AppleLanguages"]; 
    } 
} 
@end 

使用上面的類引用的字符串的文件/圖像/視頻/等:

// Access a localized image 
[[OSLocalization currentLanguageBundle] pathForResource:@"my_image_name.png" ofType:nil] 
// Access a localized string from Localizable.strings file 
NSLocalizedStringFromTableInBundle(@"StringKey", nil, [OSLocalization currentLanguageBundle], @"comment") 

更改語言的在線像下面或更新的類「changeCurrentLanguage」方法以上取一個引用新語言代碼的字符串參數。

// Change the preferred language to Spanish 
[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"]; 
相關問題