在iPhone上NSLocalizedString返回iPhone语言的字符串。 是否有可能强制NSLocalizedString使用特定语言来拥有应用程序 用不同的语言吗?


当前回答

通过从应用程序中选择特定语言来使用特定语言的技巧是强制NSLocalizedString使用特定的bundle,这取决于所选的语言,

这是我为此写的一篇文章 学习ios应用的高级本地化

这是ios应用程序中一个示例应用程序的高级本地化代码

其他回答

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

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

如果你想使用标准方法(使用NSLocalizedString)你可以在所有文件中做一个快速的语法替换。

根据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

使用上面的类来引用一个字符串文件/图像/视频/等等:

// 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")

像下面这样inline更改language或更新上面类中的"changeCurrentLanguage"方法,以获取引用新语言的字符串参数。

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

对我来说,测试计划用户,在测试计划的参数中指定- applellanguages (en_BZ)(英语伯利兹语)在启动时传递是有效的。

因为我们使用en_GB和en_BZ, iOS总是首选en_GB。即便如此,当我将设备语言切换到EN,区域切换到BZ,以及在测试计划应用程序语言和应用程序区域设置中设置这些值时。除了上面的老方法,什么都没用:)

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

// 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马可重新定义。也许有人能帮我修好这部分。

你可以这样做:

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


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

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