如何在运行时更改iPhone应用程序语言?

如何在运行时更改iPhone应用程序语言?,iphone,internationalization,performance,Iphone,Internationalization,Performance,有没有办法在运行时更改应用程序语言 因此,在更改后,NSLocalizedString立即返回新语言的字符串 我现在所做的是使用以下代码更改语言: - (void)onChangeLanguage: (id)sender { NSArray *lang = [NSArray arrayWithObjects:((InfoWhatever *)sender).language, nil]; [[NSUserDefaults standardUserDefaults] setObj

有没有办法在运行时更改应用程序语言

因此,在更改后,
NSLocalizedString
立即返回新语言的字符串

我现在所做的是使用以下代码更改语言:

- (void)onChangeLanguage: (id)sender 
{
    NSArray *lang = [NSArray arrayWithObjects:((InfoWhatever *)sender).language, nil];
    [[NSUserDefaults standardUserDefaults] setObject:lang forKey:@"AppleLanguages"];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
    NSString *currentLanguage = [languages objectAtIndex:0];

    NSLog(@"Current language: %@", currentLanguage);
}

语言将更改,但只有在重新启动应用程序后才能更改。

我怀疑您是否能做到这一点,即使设置应用程序也不能做到


(当你在设置应用程序中更改语言时,屏幕变黑,显示“设置语言…”和一个进度轮。经过长时间的等待,你回到了Springboard。看起来手机几乎要重新启动了。)

从应用程序中选择特定语言的诀窍是根据所选语言强制NSLocalizedString使用特定捆绑包

这是我为此写的帖子


下面是一个示例应用程序的代码,您可以这样做。这是路

  • 简而言之,下载并向项目中添加2个文件

  • 2
    #导入“LocalizationSystem.h”

    三,

    4在您设置上述语言之后

    AMLocalizedString(@"Key", nil)
    

    就是这样

    我想出了一个解决方案,允许您使用
    NSLocalizedString
    。我创建了一个类别
    NSBundle
    call
    NSBundle+RunTimeLanguage
    。界面是这样的

    // NSBundle+RunTimeLanguage.h
    #import <Foundation/Foundation.h>
    @interface NSBundle (RunTimeLanguage)
    #define NSLocalizedString(key, comment) [[NSBundle mainBundle] runTimeLocalizedStringForKey:(key) value:@"" table:nil]
    - (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName;
    @end
    
    // NSBundle+RunTimeLanguage.m
    #import "NSBundle+RunTimeLanguage.h"
    #import "AppDelegate.h"
    
    @implementation NSBundle (RunTimeLanguage)
    
    - (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
    {
        AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
        NSString *path= [[NSBundle mainBundle] pathForResource:[appDelegate languageCode] ofType:@"lproj"];
        NSBundle *languageBundle = [NSBundle bundleWithPath:path];
        NSString *localizedString=[languageBundle localizedStringForKey:key value:key table:nil];
        return localizedString;
    }
    @end
    
    而不仅仅是将import
    NSBundle+RunTimeLanguage.h
    添加到使用
    NSLocalizedString
    的文件中

    如您所见,我将语言代码存储在
    AppDelegate
    的属性中。这可以存放在你想要的任何地方

    我唯一不喜欢的是一个警告,
    NSLocalizedString
    marco重新定义了它。也许有人能帮我修理这个零件。

    试试这个: 对象_setClass([NSBundle mainBundle],[MyBundle class])


    只需添加以下行:

     #define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]   
    
    
     1. NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; 
                [defaults setObject:@[@"en"] forKey:@"AppleLanguages"];  [defaults
                synchronize];
    
     2. _label.text = NSLocalizedStringFromTableInBundle(@"Key", nil, currentLanguageBundle, @"");
    

    FWIW,这也是它在桌面(Mac)上的工作原理。运行的应用程序不受语言更改的影响。我刚刚回答了一个类似的问题,并发布了一些代码[此处][1][1]:在我的应用程序中有一个阿拉伯语和英语的设置页面。一旦我更改了语言,它应该翻转视图控制器和NSLocalizedString。它只在我重新启动应用程序时起作用。但它应该在不关闭应用程序的情况下改变,是吗?我同意你的假设-但这不是一个答案。你有关于执行运行时语言更改的任何信息吗?@Brandon:这是对另一个问题的回答。我的回答的措辞很明显,它是基于假设和观察,而不是基于一些第一手资料(如果我有,我会引用这些资料)。没有人给出不同(更好)的答案,所以我仍然认为这是正确的答案。是的,这是一个不同的问题。看看答案,回答者显然对主题有一些第一手的知识——即使问题没有完全解决。你的回答绝对没有提供任何有用的信息。“设置应用程序无法做到这一点”的说法不仅是错误的,而且具有误导性。为什么设置应用程序在运行时不(而不是不能)更改表示语言很重要?询问者所追求的用例不需要重新显示本地化图标,甚至不需要涉及其他应用程序。布兰登:你为什么不和我们分享你的答案?我花了好长时间才想出一个解决办法。实际上,我最终使用了“NSLocalizedStringFromTable”宏和“AppleLanguages”设置来设置和检查语言设置。如果有机会,我会写一份真实的答案。也许你应该删除这个答案?看到一个空洞但被接受的答案并不能激励任何人付出大量的努力。这是正确的方法,但这里有一个更简单的实现:这个实现更好。ThomasW正在替换数组的原始内容。这个方法是在已经存在的语言之上插入语言。这是如何工作的?至少对于iOS 8.2“[userDefaults objectForKey:@“AppleLanguages”];”返回不可变数组这会导致崩溃:[uuu NSArrayI insertObject:atIndex:]:发送到实例0x6080003C580的无法识别的选择器这听起来是解决问题的正确方法,但是因为您没有直接使用NSLocalizedString(或其变体),您将无法使用genstring生成字符串表。不过,您可能可以使用genstring的这个开源实现来检测您的函数:但是,图像资源呢。如果一个屏幕上有许多图像,我们必须明确设置它们。有更好的图像处理方法吗?您可以在定义图像之前“取消定义NSLocalizedString”。这应该可以删除警告。是否可以使用此方法来本地化情节提要?我在项目中尝试了您的解决方案,但遇到了一个例外:“路径上似乎没有有效的已编译情节提要”。然后我注意到原因是我在故事板中启用了大小类。如果为情节提要启用大小类,项目也会发生同样的情况。你知道如何解决这个问题吗?问题是关于“运行时切换”。你建议重建。
    // NSBundle+RunTimeLanguage.m
    #import "NSBundle+RunTimeLanguage.h"
    #import "AppDelegate.h"
    
    @implementation NSBundle (RunTimeLanguage)
    
    - (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
    {
        AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
        NSString *path= [[NSBundle mainBundle] pathForResource:[appDelegate languageCode] ofType:@"lproj"];
        NSBundle *languageBundle = [NSBundle bundleWithPath:path];
        NSString *localizedString=[languageBundle localizedStringForKey:key value:key table:nil];
        return localizedString;
    }
    @end
    
     #define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]   
    
    
     1. NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; 
                [defaults setObject:@[@"en"] forKey:@"AppleLanguages"];  [defaults
                synchronize];
    
     2. _label.text = NSLocalizedStringFromTableInBundle(@"Key", nil, currentLanguageBundle, @"");