在iOS中更改应用程序语言而无需重新启动应用程序

Rya*_*yan 29 xcode cocoa localization objective-c ios

我似乎有些应用程序可以在应用程序内部更改语言,而无需重新启动应用程序,我想知道它们是如何实现的.

例如,对于我们使用NSLocalizedString,我知道可以在运行时在未初始化main.m时设置语言AppDelegate,但是一旦初始化(特别是创建了视图控制器),更改它直到下次重新启动才会生效

[[NSUserDefaults standardUserDefaults] 
    setObject:[NSMutableArray arrayWithObjects:language, nil] 
    forKey:@"AppleLanguages"];
Run Code Online (Sandbox Code Playgroud)

任何人都知道如何在不重新启动应用程序的情况下完成这些动态语言更改?

Mer*_*erk 5

这里有一些其他方法的讨论,特别是基于通知的方法:

iOS:如何以编程方式更改应用程序语言而不重新启动应用程序?

在我看来,这里确实有三个任务:(1)从笔尖自动加载的资源的重新定位.(例如,如果您从笔尖动态实例化另一个自定义UIView,则仍将加载"旧"语言字符串和设置(图像,文本方向))(2)重新定位当前显示在屏幕上的字符串.(3)在程序代码中重新定位开发人员(你)插入的字符串.

让我们从(3)开始.如果您查找定义,您会注意到NSLocalizedString是一个宏.因此,如果您不想过多地更改现有代码,则可以通过创建新的头文件来解决(3)的问题.在该头文件中,#undef然后#define NSLocalizedString从适当的位置重新选择本地化字符串 - 不是iOS默认的那个,而是在某个全局变量中跟踪的那个(例如,在app delegate ivar中).如果您不想重新定义NSLocalizedString,但仍然可以自己选择,那么#undef NSLocalizedString如果您不希望未来的开发人员意外地调用它而不是您替换它的宏,您应该仍然可以.不是一个理想的解决方案,但也许是最实用的.

至于(1),如果你还没有在Interface Builder中进行本地化,而是在viewDidLoad等中动态地进行本地化,没问题.您可以使用刚才讨论过的相同行为(即修改后的NSLocalizedString等).否则,你可以(a)实现上面链接(复杂)中描述的通知系统,或者(b)考虑将本地化从IB移动到viewDidLoad,或者(c)尝试覆盖initWithNibName:并交换用旧语言资源加载的对象,其中一个装载了新的语言资源.这是Mohamed在本次讨论的最底层提到的一种方法:http://learning-ios.blogspot.ca/2011/04/advance-localization-in-ios-apps.html.他声称它会导致问题(未调用viewDidLoad).即使它不起作用,尝试它可能会指向你做的事情.

最后,(2)可能是最简单的任务:只需删除并重新添加当前视图(或者在某些情况下,只需重绘它).


hol*_*lex 2

我一直用这个方法,效果很好,也许对你也有帮助。

\n
\n

您应该在every 的方法中设置当前语言的NSLocalizableString(...)所有文本。UI-viewWillAppear:UIViewController

\n

使用这种方式,您(我的意思是用户)在更改“设置”中的语言后不需要重新启动应用程序。iOS

\n
\n

当然,我使用的是苹果的标准本地化架构。

\n

更新日期(2013 年 10 月 24 日)

\n

我经历过\xe2\x80\x93viewWillAppear:当应用程序进入前台时,该方法不会对实际视图执行;UIApplicationWillEnterForegroundNotification为了解决这个问题,当我在视图中收到通知时,我还会提交该过程(见上文) 。

\n

  • 但这并没有回答如何明智地进行编程的问题 (5认同)