为了账号安全,请及时绑定邮箱和手机立即绑定

如何强制NSLocalizedString使用特定语言

如何强制NSLocalizedString使用特定语言

iOS
桃花长相依 2019-06-03 16:22:31
如何强制NSLocalizedString使用特定语言在iPhone上NSLocalizedString返回iPhone语言中的字符串。有没有可能强迫NSLocalizedString使用一种特定的语言使应用程序使用与设备不同的语言?
查看完整描述

4 回答

?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

请勿在iOS 9上使用。这将对通过它传递的所有字符串返回零。


我找到了另一个解决方案,允许您更新语言字符串,w/o重新启动应用程序,并与genstring兼容:


将这个宏放在前缀中.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, @""));


查看完整回答
反对 回复 2019-06-03
?
富国沪深

TA贡献1790条经验 获得超9个赞

NSLocalizedString()中的“AppleLanguage”键(及其变体)NSUserDefaults若要确定用户对首选语言的设置,请执行以下操作。这将返回一个语言代码数组,第一个代码是用户为其手机设置的代码,如果资源在首选语言中不可用,则返回后续代码作为后备。(在桌面上,用户可以使用系统首选项中的自定义顺序指定多种语言)

如果您愿意,可以通过使用setObject:Forkey:Method设置您自己的语言列表来覆盖您自己的应用程序的全局设置。这将优先于全局设置值,并返回到正在执行本地化的应用程序中的任何代码。用于此的代码如下所示:

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

这将使德语成为您的应用程序的首选语言,以英语和法语作为后盾。您可能希望在应用程序启动的早期就将其命名为此。您可以在这里阅读更多关于语言/区域设置的首选项:国际化编程主题:获取当前语言和地区


查看完整回答
反对 回复 2019-06-03
?
波斯汪

TA贡献1811条经验 获得超4个赞

我最近也有同样的问题,我不想开始修补我的整个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"];

若要重置为系统默认值,只需传递0:

[NSBundle setLanguage:nil];

好好享受.。

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

var bundleKey: UInt8 = 0class 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)
    }}


查看完整回答
反对 回复 2019-06-03
?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

我通常是这样做的,但是您必须在您的项目中拥有所有的本地化文件。

@implementation Languagestatic 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


查看完整回答
反对 回复 2019-06-03
  • 4 回答
  • 0 关注
  • 1156 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信