我想要显示设备UI使用的当前语言。我应该使用什么代码?

我想把它作为一个NSString完全拼写出来的格式。(@ en_US)

编辑:对于那些开车路过的人来说,这里有大量有用的评论,因为随着新iOS版本的发布,答案也在不断变化。


当前回答

接受的答案和其他答案都没有考虑到首选语言可以是设备语言以外的另一种语言。

设备语言是操作系统元素和苹果应用程序所使用的语言。

首选语言是用户希望应用程序本地化的语言。苹果只提供有限的一组翻译。如果首选语言是苹果将其应用程序翻译成的一种语言,那么它也将是设备语言。但是,如果用户喜欢苹果没有提供翻译的语言,那么设备和首选语言将不匹配。设备语言将不在首选语言列表的第一位置。

下面的函数将遍历首选语言列表,并检查Apple框架中是否有翻译。第一种有翻译的语言是设备语言。函数将返回其语言代码。

func deviceLanguage() -> String? {
    let systemBundle: NSBundle = NSBundle(forClass: UIView.self)
    let englishLocale: NSLocale = NSLocale(localeIdentifier: "en")

    let preferredLanguages: [String] = NSLocale.preferredLanguages()

    for language: String in preferredLanguages {
        let languageComponents: [String : String] = NSLocale.componentsFromLocaleIdentifier(language)

        guard let languageCode: String = languageComponents[NSLocaleLanguageCode] else {
            continue
        }

        // ex: es_MX.lproj, zh_CN.lproj
        if let countryCode: String = languageComponents[NSLocaleCountryCode] {
            if systemBundle.pathForResource("\(languageCode)_\(countryCode)", ofType: "lproj") != nil {
                // returns language and country code because it appears that the actual language is coded within the country code aswell
                // for example: zh_CN probably mandarin, zh_HK probably cantonese
                return language
            }
        }

        // ex: English.lproj, German.lproj
        if let languageName: String = englishLocale.displayNameForKey(NSLocaleIdentifier, value: languageCode) {
            if systemBundle.pathForResource(languageName, ofType: "lproj") != nil {
                return languageCode
            }
        }

        // ex: pt.lproj, hu.lproj
        if systemBundle.pathForResource(languageCode, ofType: "lproj") != nil {
            return languageCode
        }
    }

    return nil
}

如果首选语言列表是:

南非荷兰语(iOS不翻译成南非荷兰语) 西班牙语(设备语言)

首选语言列表可在“设置”中编辑。app ->通用->语言和地区->首选语言顺序


您可以使用设备语言代码并将其转换为语言名称。下面几行将以设备语言打印设备语言。例如,如果设备设置为西班牙语,则为“Español”。

if let deviceLanguageCode: String = deviceLanguage() {
    let printOutputLanguageCode: String = deviceLanguageCode
    let printOutputLocale: NSLocale = NSLocale(localeIdentifier: printOutputLanguageCode)

    if let deviceLanguageName: String = printOutputLocale.displayNameForKey(NSLocaleIdentifier, value: deviceLanguageCode) {
        // keep in mind that for some localizations this will print a language and a country
        // see deviceLanguage() implementation above
        print(deviceLanguageName)
    }
} 

其他回答

如果你正在寻找首选语言代码(“en”,“de”,“es”…),和本地化的首选语言名称(当前地区),这里有一个简单的Swift扩展:

extension Locale {
    static var preferredLanguageIdentifier: String {
        let id = Locale.preferredLanguages.first!
        let comps = Locale.components(fromIdentifier: id)
        return comps.values.first!
    }

    static var preferredLanguageLocalizedString: String {
        let id = Locale.preferredLanguages.first!
        return Locale.current.localizedString(forLanguageCode: id)!
    }
}

你可以使用NSLocale的displayNameForKey:value:方法:

// get a French locale instance
NSLocale *frLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"] autorelease];

// use it to get translated display names of fr_FR and en_US
NSLog(@"%@", [frLocale displayNameForKey:NSLocaleIdentifier value:@"fr_FR"]);
NSLog(@"%@", [frLocale displayNameForKey:NSLocaleIdentifier value:@"en_US"]);

这将打印出:

français (France)
anglais (États-Unis)

如果你为initWithLocaleIdentifier:和displayNameForKey:value:方法指定了相同的语言环境标识符,那么它会给你语言的本机名称。我发现,如果你删除国家代码,只使用fr和en,它也会从显示名称中省略国家(至少在Mac OS X上,不确定iOS)。

根据苹果文档

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];

这可能会给你你想要的:

NSLocale *locale = [NSLocale currentLocale];

NSString *language = [locale displayNameForKey:NSLocaleIdentifier 
                                         value:[locale localeIdentifier]];

它会在语言本身中显示语言的名称。 例如:

Français (France)
English (United States)

显然,解决方案依赖于,例如

[[NSLocale preferredLanguages] objectAtIndex:0]

通常工作正常,并返回当前设备语言。

但在某些情况下,它可能会产生误导:

如果你想要获取这个值的应用程序已经改变了语言,例如使用这样的代码:

NSString *lg = @"en"; // or anything like @"en", @"fr", etc.
[[NSUserDefaults standardUserDefaults] 
    setObject:[NSArray arrayWithObjects:lg, nil]  
    forKey:@"AppleLanguages"]

在这种情况下,[NSLocale preferredLanguages]实际上返回这个特定应用程序的首选语言集(和使用),而不是当前设备语言!

和…在这种情况下,正确获得实际当前设备语言(而不是之前在应用程序中设置的语言)的唯一方法是首先清除NSUserDefaults中的@"appleLanguages"键,像这样:

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

然后,[NSLocale preferredLanguages]现在返回正确的值。

希望这对你有所帮助。