2012-08-30 42 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"]; 
相关问题