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


当前回答

对于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))

同时移除你的AppDelegate.swift文件中的@UIApplicationMain。

其他回答

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

我的解决方案是动态地改变主bundle的类,并在那里加载适当的bundle:

头文件

@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)
    }
}

NSLocalizedString() reads the value for the key AppleLanguages from the standard user defaults ([NSUserDefaults standardUserDefaults]). It uses that value to choose an appropriate localization among all existing localizations at runtime. When Apple builds the user defaults dictionary at app launch, they look up the preferred language(s) key in the system preferences and copy the value from there. This also explains for example why changing the language settings in OS X has no effect on running apps, only on apps started thereafter. Once copied, the value is not updated just because the settings change. That's why iOS restarts all apps if you change then language.

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

所以如果你想改变语言只是为了测试,你可能不想改变你的代码(如果你忘记删除这段代码…),而是告诉Xcode用一个命令行参数启动你的应用程序(例如使用西班牙语本地化):

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

无论你做什么,最好的方法是获取指定语言的short_name,即:fr, en, nl, de, it,等等…并将其赋值为全局值。

使选择器视图像下拉菜单一样弹出(单击一个按钮,选择器视图从下面出现一个语言列表),并选择您想要的语言。让短名称存储在内部。 创建一个名为LocalisedString的.h + .m文件。

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

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

没有违反规则。

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

给出了一些可以使用的语言代码的例子。希望这能有所帮助

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

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

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