ios java语言_iOS开发之APP内部切换语言

前言

iOS开发中,随着APP越来越完善,很多APP都做了国际化,也实现了APP内部切换语言。

原理

国际化都会走到NSBundle的- (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName方法,使用自定义Bundle替换NSBundle,通过切换根控制器来完成APP内部切换语言。

1.拦截国际化方法

通过分类和runtime来实现拦截,将Bundle替换为自定义CLBundle。

+ (void)load {

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

//动态继承、交换,方法类似KVO,通过修改[NSBundle mainBundle]对象的isa指针,使其指向它的子类CLBundle,这样便可以调用子类的方法;其实这里也可以使用method_swizzling来交换mainBundle的实现,来动态判断,可以同样实现。

object_setClass([NSBundle mainBundle], [CLBundle class]);

});

}

复制代码

2.重写方法判断加载哪一种语言

重写mainBundle方法,通过语言管理类获取当前应该加载哪一种语言。

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {

if ([CLBundle cl_mainBundle]) {

return [[CLBundle cl_mainBundle] localizedStringForKey:key value:value table:tableName];

} else {

return [super localizedStringForKey:key value:value table:tableName];

}

}

+ (NSBundle *)cl_mainBundle {

if ([NSBundle currentLanguage].length) {

NSString *path = [[NSBundle mainBundle] pathForResource:[NSBundle currentLanguage] ofType:@"lproj"];

if (path.length) {

return [NSBundle bundleWithPath:path];

}

}

return nil;

}

+ (NSString *)currentLanguage {

return [CLLanguageManager userLanguage] ? : [NSLocale preferredLanguages].firstObject;

}

复制代码

3.语言管理类

将语言切换调用设置简单封装,方便调用。

+ (void)setUserLanguage:(NSString *)userLanguage {

//跟随手机系统

if (!userLanguage.length) {

[self resetSystemLanguage];

return;

}

//用户自定义

[[NSUserDefaults standardUserDefaults] setValue:userLanguage forKey:CLUserLanguageKey];

[[NSUserDefaults standardUserDefaults] setValue:@[userLanguage] forKey:@"AppleLanguages"];

[[NSUserDefaults standardUserDefaults] synchronize];

}

+ (NSString *)userLanguage {

return [[NSUserDefaults standardUserDefaults] valueForKey:CLUserLanguageKey];

}

/**

重置系统语言

*/

+ (void)resetSystemLanguage {

[[NSUserDefaults standardUserDefaults] removeObjectForKey:CLUserLanguageKey];

[[NSUserDefaults standardUserDefaults] setValue:nil forKey:@"AppleLanguages"];

[[NSUserDefaults standardUserDefaults] synchronize];

}

复制代码

4.切换根控制器来切换语言

为了减少工作量,直接切换根控制器来达到语言切换。

[CLLanguageManager setUserLanguage:@"en"];

CLTabbarController *tabbarController = [[CLTabbarController alloc] init];

tabbarController.selectedIndex = 3;

UINavigationController *navigationController = tabbarController.selectedViewController;

NSMutableArray *viewControllers = navigationController.viewControllers.mutableCopy;

//取出我的页面,提前加载,解决返回按钮不变化

CLMyController *me = (CLMyController *)[viewControllers firstObject];

[me loadViewIfNeeded];

//新建设置语言页面

CLChangeLanguageController *languageController = [[CLChangeLanguageController alloc] init];

languageController.hidesBottomBarWhenPushed = YES;

[viewControllers addObject:languageController];

//解决奇怪的动画bug。

dispatch_async(dispatch_get_main_queue(), ^{

[UIApplication sharedApplication].keyWindow.rootViewController = tabbarController;

navigationController.viewControllers = viewControllers;

CLLog(@"已切换到语言 %@", [NSBundle currentLanguage]);

});

复制代码

效果图

87b4eb282a44782f55893ecc6e1e7e38.gif

总结

以上是使用国际化来实现APP内部切换语言,希望能够给大家帮助,demo地址--->>CLDemo

https://github.com/JmoVxia/CLDemo

链接:https://juejin.im/post/5c130156e51d451d9a74887b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值