美文网首页iOS新手学习开发知识
iOS国际化遇到的那些坑

iOS国际化遇到的那些坑

作者: 男人的担当 | 来源:发表于2018-04-02 17:02 被阅读164次

本文主要讲述国际化过程中所遇到的那些问题,国际化的详细步骤可以参考:3分钟实现iOS语言本地化/国际化(图文详解)

  • APP内设置了语言,切换后语言没有生效
 [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:language, nil] forKey:@"AppleLanguages"];
  [[NSUserDefaults standardUserDefaults] synchronize];

没有生效,这是因为设置AppleLanguages字段的话,只会在下次启动App才会生效,在App启动后就已经生成了一个Bundle,里面识别好了对应着AppleLanguages的国际化文件,在App运行期间设置这个字段,是不生效的,所以我们去修改这个Bundle,写一个NSBundle的扩展,这里要用到runtime中的关联:
.h

#import <Foundation/Foundation.h>

@interface NSBundle (Language)

+ (void)setLanguage:(NSString *)language;

@end

.m

#import "NSBundle+Language.h"
#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来把一个对象与另外一个对象进行关联。该函数需要四个参数:源对象,关键字,关联的对象和一个关联策略。
     *关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字。
     */
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

然后在选中语言的时候,重新设置根控制器

- (IBAction)clickEvent:(id)sender {
    [self changeLanguageTo:@"zh-Hans"];
}

- (IBAction)selectBtnEvent:(id)sender {
    [self changeLanguageTo:@"en"];
}
- (void)changeLanguageTo:(NSString *)language {
    // 设置语言
    [NSBundle setLanguage:language];
    
    // 然后将设置好的语言存储好,下次进来直接加载
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:@"myLanguage"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    //重新设置根控制器
    ViewController *VC = [[ViewController alloc] init];
    [UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor whiteColor];
    [UIApplication sharedApplication].keyWindow.rootViewController = VC;
}

然后你会发现:如果这个根控制器直接用storyboard或者XIB的话,里面view会消失了。这是因为:重新设置了根控制器时,会执行

- (void)viewDidLoad {
    [super viewDidLoad];
}

如果不是在这里初始化的控件,是无法加载进来的。

  • 如果使用

#define NSLocalizedString(key, comment) \ [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
这个方法,加载的key中间有空格的话,例如:I like,即使点击改变了语言,但是它还是保持原来语言的情况。

写的比较乱,可以参考demoiOS国际化

相关文章

  • iOS国际化遇到的那些坑

    本文主要讲述国际化过程中所遇到的那些问题,国际化的详细步骤可以参考:3分钟实现iOS语言本地化/国际化(图文详解)...

  • iOS开发中遇到过的坑

    iOS开发中遇到过的坑 iOS开发中遇到过的坑

  • cocoaPods 打包静态库 遇到的坑 and git

    cocoaPods 打包静态库 遇到的坑参考资料iOS 打包.a文件的那些事儿iOS-将自己的库支持CocoaPo...

  • 国际化简体中文和繁体中文的坑

    安卓资源国际化的坑---中文 今天遇到一个国际化的坑,就是在进行繁体中文和简体中文国际化的时候,中文一套,繁体中文...

  • 【iOS开发】iOS上线遇到的那些坑

    首先,先放篇上线的教程,以备不时之需:审核注意事项 其实前面证书的配置,一般进行过真机调试,又是一个人开发的,基本...

  • Ng Alain国际化不显示中文

    Ng Alain今天遇到的坑是国际化,就是不显示中文,结果把 private _langs = [ { cod...

  • IOS的国际化

    久未提笔,学习过程中处处遇坑,踩过得坑分享一下,希望再遇到这些坑的猿们能直接越过.... 国际化: 一、In...

  • 项目开发相关文章

    iOS国际化

  • IOS 遇到的坑

    IOS 开发值网络权限和跳转系统的指定界面 在开发中APP 首次安装的时候,会弹出一个是否允许APP 访问网络...

  • 遇到的那些坑

    1、为了优化代码增加了配置文件,用Python自带的模块configparser。中间增加了公共方法所在目录,导致...

网友评论

本文标题:iOS国际化遇到的那些坑

本文链接:https://www.haomeiwen.com/subject/xmrxhftx.html