如何强制NSLocalizedString使用特定语言

时间:2009-11-03 19:33:19

标签: ios objective-c localization internationalization nslocalizedstring

在iPhone上NSLocalizedString返回iPhone语言的字符串。 是否可以强制NSLocalizedString使用特定语言来获取应用 用不同于设备的语言?

28 个答案:

答案 0 :(得分:251)

NSLocalizedString()(及其变体)访问NSUserDefaults中的“AppleLanguages”键,以确定用户对首选语言的设置。这将返回一组语言代码,第一个是用户为其手机设置的语言代码,如果资源不是首选语言,则后续用作后备。 (在桌面上,用户可以在“系统偏好设置”中使用自定义排序指定多种语言)

如果您希望使用setObject:forKey:方法设置自己的语言列表,则可以覆盖自己应用程序的全局设置。这将优先于全局设置值,并返回到应用程序中执行本地化的任何代码。这个代码看起来像:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de", @"en", @"fr", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate

这将使德语成为您的应用程序的首选语言,英语和法语作为后备。您可能希望在应用程序启动时的某个时间调用它。您可以在此处详细了解语言/区域设置首选项:Internationalization Programming Topics: Getting the Current Language and Locale

答案 1 :(得分:141)

我最近遇到了同样的问题,我不想启动并修补我的整个 NSLocalizedString ,也不强迫应用重启以使新语言正常工作。我希望一切都按原样运作。

我的解决方案是动态更改主包的类并在那里加载适当的包:

标头文件

@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end

<强>实施

#import <objc/runtime.h>

static const char _bundle=0;

@interface BundleEx : NSBundle
@end

@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}
@end

@implementation NSBundle (Language)
+(void)setLanguage:(NSString*)language
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
    {
        object_setClass([NSBundle mainBundle],[BundleEx class]);
    });
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

所以基本上,当你的应用程序启动时,在加载第一个控制器之前,只需调用:

[NSBundle setLanguage:@"en"];

当您的用户在设置屏幕中更改其首选语言时,只需再次调用它:

[NSBundle setLanguage:@"fr"];

要重置回系统默认值,只需传递nil:

[NSBundle setLanguage:nil];

...享受

对于那些需要Swift版本的人:

var bundleKey: UInt8 = 0

class AnyLanguageBundle: Bundle {

    override func localizedString(forKey key: String,
                                  value: String?,
                                  table tableName: String?) -> String {

        guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,
              let bundle = Bundle(path: path) else {

            return super.localizedString(forKey: key, value: value, table: tableName)
            }

        return bundle.localizedString(forKey: key, value: value, table: tableName)
    }
}

extension Bundle {

    class func setLanguage(_ language: String) {

        defer {

            object_setClass(Bundle.main, AnyLanguageBundle.self)
        }

        objc_setAssociatedObject(Bundle.main, &bundleKey,    Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

答案 2 :(得分:136)

我通常以这种方式执行此操作,但您必须在项目中拥有所有本地化文件。

@implementation Language

static NSBundle *bundle = nil;

+(void)initialize 
{
    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    NSArray* languages = [defs objectForKey:@"AppleLanguages"];
    NSString *current = [[languages objectAtIndex:0] retain];
    [self setLanguage:current];
}

/*
  example calls:
    [Language setLanguage:@"it"];
    [Language setLanguage:@"de"];
*/
+(void)setLanguage:(NSString *)l
{
    NSLog(@"preferredLang: %@", l);
    NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
    bundle = [[NSBundle bundleWithPath:path] retain];
}

+(NSString *)get:(NSString *)key alter:(NSString *)alternate 
{
    return [bundle localizedStringForKey:key value:alternate table:nil];
}

@end

答案 3 :(得分:41)

不要在iOS 9上使用。对于通过它的所有字符串,都会返回nil。

我找到了另一种解决方案,允许您更新语言字符串,无需重新启动应用程序并与genstrings兼容:

将此宏放在Prefix.pch中:

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]

并且您需要使用本地化字符串:

NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"")

设置语言使用:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];

即使是连续的语言跳跃也能正常工作,如:

NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"fr"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"it"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));

答案 4 :(得分:31)

如前所述,只需:

[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];

但是为了避免重新启动应用,请将行放在main.m的主方法中,就在UIApplicationMain(...)之前。

答案 5 :(得分:31)

通过从应用程序中选择特定语言来使用特定语言的技巧是强制NSLocalizedString根据所选语言使用特定包,

这是我为此写的帖子 learning advance localization in ios apps

以下是一个示例应用advance localization in ios apps

的代码

答案 6 :(得分:11)

NSLocalizedString()从标准用户默认值(AppleLanguages)中读取密钥[NSUserDefaults standardUserDefaults]的值。它使用该值在运行时在所有现有本地化中选择适当的本地化。当Apple在应用程序启动时构建用户默认字典时,他们会在系统首选项中查找首选语言键并从中复制值。这也解释了为什么更改OS X中的语言设置对运行应用程序没有影响,仅限于此后启动的应用程序。复制后,仅因为设置更改而不更新该值。这就是为什么iOS会重新启动所有应用程序,如果您更改语言。

但是,用户默认字典的所有值都可以被命令行参数覆盖。请参阅NSUserDefaults上的NSArgumentDomain文档。这甚至包括从app首选项(.plist)文件加载的值。如果您只想更改一次值以进行测试,那么非常了解

因此,如果您只想更改语言以进行测试,您可能不希望更改代码(如果您以后忘记删除此代码...),而是告诉Xcode使用命令启动您的应用程序行参数(例如使用西班牙语本地化):

enter image description here

根本不需要触摸您的代码。只需为不同的语言创建不同的方案,您只需切换方案,就可以用一种语言快速启动应用程序一次,在另一种语言中启动一次。

答案 7 :(得分:11)

我最喜欢Mauro Delrio的方法。 我还在Project_Prefix.pch中添加了以下内容

#import "Language.h"    
#define MyLocalizedString(key, alt) [Language get:key alter:alt]

因此,如果您想使用标准方法(使用NSLocalizedString),您可以在所有文件中进行快速语法替换。

答案 8 :(得分:11)

正如布莱恩韦伯斯特所提到的那样,语言需要在应用程序创建初期的某个时间设置。我认为applicationDidFinishLaunching:的{​​{1}}应该是一个合适的地方,因为它是我进行所有其他初始化的地方。

但正如威廉·丹尼斯所提到的那样,只有之后重新启动应用程序才会产生效果,这有点无用。

如果我把代码放在main函数中似乎工作正常,但是:

AppDelegate

我对此有任何意见表示感谢。

答案 9 :(得分:10)

我想出了一个允许你使用NSLocalizedString的解决方案。我创建了一个NSBundle来电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

只需将导入NSBundle+RunTimeLanguage.h添加到使用NSLocalizedString的文件中即可。

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

我唯一不喜欢的是NSLocalizedString marco重新定义的警告。也许有人可以帮我解决这个问题。

答案 10 :(得分:9)

Swift版本:

NSUserDefaults.standardUserDefaults().setObject(["fr"], forKey: "AppleLanguages")
NSUserDefaults.standardUserDefaults().synchronize()

答案 11 :(得分:8)

简而言之:

本地化您的应用程序

您要做的第一件事就是使用至少两种语言(本例中为英语和法语)本地化您的应用。

覆盖NSLocalizedString

在您的代码中,使用定义如下的宏NSLocalizedString(key, comment),而不是使用MYLocalizedString(key, comment)#define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];

这个MYLocalizationSystem单身人士会:

  • 通过设置正确的本地化NSBundle 用户请求设置语言
  • 根据此前设置的语言
  • 返回本地化的NSString

设置用户语言

当用户使用法语更改应用程序语言时,请致电[[MYLocalizationSystem sharedInstance] setLanguage:@"fr"];

- (void)setLanguage:(NSString *)lang
{
    NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj"];
    if (!path)
    {
        _bundle = [NSBundle mainBundle];
        NSLog(@"Warning: No lproj for %@, system default set instead !", lang);
        return;
    }

    _bundle = [NSBundle bundleWithPath:path];
}

在此示例中,此方法将本地化的包设置为fr.lproj

返回本地化字符串

一旦您设置了本地化的捆绑包,您就可以使用此方法从他那里获得正确的本地化字符串:

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value
{
    // bundle was initialized with [NSBundle mainBundle] as default and modified in setLanguage method
    return [self.bundle localizedStringForKey:key value:value table:nil];
}

希望这会对你有所帮助。

您可以在NSWinery.io

中找到本文的更多详细信息

答案 12 :(得分:7)

您如何看待Swift 3的这个解决方案?

extension String {

    func localized(forLanguage language: String = Locale.preferredLanguages.first!.components(separatedBy: "-").first!) -> String {

        guard let path = Bundle.main.path(forResource: language == "en" ? "Base" : language, ofType: "lproj") else {

            let basePath = Bundle.main.path(forResource: "Base", ofType: "lproj")!

            return Bundle(path: basePath)!.localizedString(forKey: self, value: "", table: nil)
        }

        return Bundle(path: path)!.localizedString(forKey: self, value: "", table: nil)
    }
}

简单用法:

"report".localized(forLanguage: "pl") //forced language
"report".localized() //default language selected by user in settings, in case when your app doesnt support selected lanaguage, the default one is selected, here is an english.

答案 13 :(得分:4)

也许你应该补充一下(#import之后的.pch文件):

extern NSBundle* bundle; // Declared on Language.m

#ifdef NSLocalizedString
    #undef NSLocalizedString
    // Delete this line to avoid warning
    #warning "Undefining NSLocalizedString"
#endif

#define NSLocalizedString(key, comment) \
    [bundle localizedStringForKey:(key) value:@"" table:nil]

答案 14 :(得分:4)

Swift 3扩展程序:

extension Locale {
    static var preferredLanguage: String {
        get {
            return self.preferredLanguages.first ?? "en"
        }
        set {
            UserDefaults.standard.set([newValue], forKey: "AppleLanguages")
            UserDefaults.standard.synchronize()
        }
    }
}

extension String {
    var localized: String {

    var result: String

    let languageCode = Locale.preferredLanguage //en-US

    var path = Bundle.main.path(forResource: languageCode, ofType: "lproj")

    if path == nil, let hyphenRange = languageCode.range(of: "-") {
        let languageCodeShort = languageCode.substring(to: hyphenRange.lowerBound) // en
        path = Bundle.main.path(forResource: languageCodeShort, ofType: "lproj")
    }

    if let path = path, let locBundle = Bundle(path: path) {
        result = locBundle.localizedString(forKey: self, value: nil, table: nil)
    } else {
        result = NSLocalizedString(self, comment: "")
    }
        return result
    }
}

<强>用法:

Locale.preferredLanguage = "uk"

label.text = "localizedKey".localized

答案 15 :(得分:4)

在文件 .pch 中定义:

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]


#define NSLocalizedString(str,nil) NSLocalizedStringFromTableInBundle(str, nil, currentLanguageBundle, @"")

答案 16 :(得分:3)

对于我的情况,我有两个本地化文件,ja和en

如果系统中的首选语言既不是en也不是ja

,我想强制它

我要编辑main.m文件

我将检查第一个首选项是en还是ja,如果没有,那么我将第二个首选语言更改为en。

int main(int argc, char *argv[])
{

    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"AppleLanguages"];
    [[NSUserDefaults standardUserDefaults] synchronize];

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

    if (![lang isEqualToString:@"en"]  &&  ![lang isEqualToString:@"ja"]){

        NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[NSLocale preferredLanguages]];
        [array replaceObjectAtIndex:1 withObject:@"en"];

        [[NSUserDefaults standardUserDefaults] setObject:array forKey:@"AppleLanguages"];
        [[NSUserDefaults standardUserDefaults] synchronize];


    }

    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));


    }


}

答案 17 :(得分:3)

您可以使用要执行此操作的本地化字符串集构建子包,然后使用NSLocalizedStringFromTableInBundle()加载它们。 (我假设这个内容与您在应用程序上可能正在进行的常规UI本地化分开。)

答案 18 :(得分:2)

您可以这样做:

NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:@"es"];


NSBundle *spanishBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];

NSLocalizedStringFromTableInBundle(@"House", nil, spanishBundle, nil):

答案 19 :(得分:2)

基于 Tudorizer的答案,在没有离开或重新启动应用程序的情况下更改语言。

使用类来访问首选语言,而不是宏,以检查是否存在特定的语言代码。

以下是用于获取适用于iOS 9的当前语言包的类:

@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

使用上面的类来引用字符串文件/ image / video / etc:

// 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”方法,以获取引用新语言的字符串参数。

[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];

答案 20 :(得分:2)

Swift 3解决方案:

let languages = ["bs", "zh-Hant", "en", "fi", "ko", "lv", "ms", "pl", "pt-BR", "ru", "sr-Latn", "sk", "es", "tr"]
UserDefaults.standard.set([languages[0]], forKey: "AppleLanguages")

提供了一些可以使用的语言代码示例。希望这有帮助

答案 21 :(得分:1)

这是针对此问题的一个不错的解决方案,它不需要重新启动应用程序。

https://github.com/cmaftuleac/BundleLocalization

此实现通过调整NSBundle内部来实现。我们的想法是在NSBundle对象的实例上覆盖方法localizedStringForKey,然后在另一个使用不同语言的bundle上调用此方法。简单而优雅,完全兼容所有类型的资源。

答案 22 :(得分:1)

我想添加对iOS未正式支持的语言的支持(未在系统设置下的语言部分中列出)。通过跟随Brian Webster和geon的Apple's Internationalization Tutorial和一些提示,我想出了这段代码(把它放在main.m中):

int main(int argc, char * argv[]) {
    @autoreleasepool {
        // Grab regional settings locale, for Slovenian this is either sl_SI or en_SI
        NSLocale *locale = [NSLocale currentLocale];
        NSString *ll = [locale localeIdentifier]; // sl_SI

        // Grab the first part of language identifier
        NSArray *comp = [ll componentsSeparatedByString:@"_"];
        NSString *ll1 = @"en";
        if (comp.count > 0) {
            ll1 = comp[0]; // sl, en, ...
        }
        // Check if we already saved language (user can manually change it inside app for example)
        if (![[NSUserDefaults standardUserDefaults] objectForKey:@"SelectedLanguage"]) {
            //   Slovenian (Slovenia),            Slovenia
            if ([ll isEqualToString:@"sl_SI"] || [ll isEqualToString:@"en_SI"]) {
                ll1 = @"sl-SI"; // This is the part of localized path for Slovenian language that Xcode generates
            }
            // Add more unsupported languages here...

            [[NSUserDefaults standardUserDefaults] setObject:ll1 forKey:@"SelectedLanguage"]; // Save language
        }
        else {
            // Restore language as we have previously saved it
            ll1 = [[NSUserDefaults standardUserDefaults] objectForKey:@"SelectedLanguage"];
        }
        // Overwrite NSLocalizedString and StoryBoard language preference
        [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:ll1, @"en", @"fr", nil] forKey:@"AppleLanguages"];
        // Make sure settings are stored to disk
        [[NSUserDefaults standardUserDefaults] synchronize];

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

这适用于Storyboard和NSLocalizedString代码。该代码假定用户可以选择稍后手动更改应用内的语言。

当然,不要忘记添加适当的Storyboard翻译和Localizable.strings翻译(请参阅上面的Apple页面链接,了解如何操作)。

答案 23 :(得分:1)

此函数将尝试获取当前语言的本地化字符串,如果找不到,则会使用英语语言。

- (NSString*)L:(NSString*)key
{
    static NSString* valueNotFound = @"VALUE_NOT_FOUND";
    static NSBundle* enBundle = nil;

    NSString* pl = [NSLocale preferredLanguages][0];
    NSString* bp = [[NSBundle mainBundle] pathForResource:pl ofType:@"lproj"];
    NSBundle* b = [NSBundle bundleWithPath:bp];

    NSString* s = [b localizedStringForKey:key value:valueNotFound table:nil];
    if ( [s isEqualToString:valueNotFound] ) {
        if ( !enBundle ) {
            bp = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
            enBundle = [NSBundle bundleWithPath:bp];
        }
        s = [enBundle localizedStringForKey:key value:key table:nil];
    }

    return s;
}

答案 24 :(得分:0)

无论你做什么,最好的方法是使用指定语言的short_name,即:fr,en,nl,de,it等...并将其分配给全局值。

选择一个选择器视图,就像下拉菜单一样(点击一个按钮的组合,从下面出现一个选择器视图和一个语言列表)并选择你想要的语言。让短名称存储在内部。 制作一个名为LocalisedString的.h + .m文件。

将short_name的全局值设置为等于LocalisedString.m中获取的值 选择所需语言时,指定NSBundlePath为所需语言创建项目子目录。例如,nl.proj,en.proj。

选择特定的proj文件夹时,请调用相应语言的本地化字符串并动态更改语言。

没有破坏规则。

答案 25 :(得分:0)

在Swift 4中,我无需重新启动或使用库即可解决该问题。

尝试了许多选项之后,我发现了此函数,您在其中传递了要翻译的(Localizable.String,字符串文件的)stringToLocalize,要翻译的语言以及返回的内容您在“字符串”文件中拥有的字符串的值:

    func localizeString (stringToLocalize: String, language: String) -> String
    {
        let path = Bundle.main.path (forResource: language, ofType: "lproj")
        let languageBundle = Bundle (path: path!)
        return languageBundle! .localizedString (forKey: stringToLocalize, value: "", table: nil)
    }

考虑到此功能,我在Swift文件中创建了此功能:

struct CustomLanguage {

    func createBundlePath () -> Bundle {
        let selectedLanguage = //recover the language chosen by the user (in my case, from UserDefaults)
        let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj")
        return Bundle(path: path!)!
    }
}

要从整个应用程序以及其余ViewControllers的每个字符串中进行访问,而不是放置:

NSLocalizedString ("StringToLocalize", comment: “")

我已将其替换为

let customLang = CustomLanguage() //declare at top
let bundleLanguage = customLang.createBundle()

NSLocalizedString("StringToLocalize", tableName: nil, bundle: bundleLanguage, value: "", comment: “”) //use in each String

我不知道这是否是最好的方法,但是我发现它非常简单,并且对我有用,希望对您有帮助!

答案 26 :(得分:0)

对于Swift,您可以覆盖main.swift文件,并在应用运行之前在其中设置UserDefaults字符串。这样,您无需重新启动应用程序即可看到所需的效果。

import Foundation
import UIKit

// Your initialisation code here
let langCultureCode: String = "LANGUAGE_CODE"

UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()

UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))

@UIApplicationMain文件中的AppDelegate.swift配对在一起。

答案 27 :(得分:0)

对我来说,Test-Plan 用户在 TestPlan 的 -AppleLanguages (en_BZ) 中指定 Arguments Passed On Launch(英语伯利兹)是有效的。

因为我们使用 en_GB 和 en_BZ,所以 iOS 总是首选 en_GB。即便如此,当我将设备语言切换为 EN 并将区域切换为 BZ 并在测试计划 Application LanguageApplication Region 设置中设置这些值时。除了上面的旧参数方法外,没有任何帮助:)

enter image description here