当前位置:   article > 正文

iOS开发之APP内部切换语言

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。

  1. + (void)load {
  2. static dispatch_once_t onceToken;
  3. dispatch_once(&onceToken, ^{
  4. //动态继承、交换,方法类似KVO,通过修改[NSBundle mainBundle]对象的isa指针,使其指向它的子类CLBundle,这样便可以调用子类的方法;其实这里也可以使用method_swizzling来交换mainBundle的实现,来动态判断,可以同样实现。
  5. object_setClass([NSBundle mainBundle], [CLBundle class]);
  6. });
  7. }
  8. 复制代码
2.重写方法判断加载哪一种语言

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

  1. - (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
  2. if ([CLBundle cl_mainBundle]) {
  3. return [[CLBundle cl_mainBundle] localizedStringForKey:key value:value table:tableName];
  4. } else {
  5. return [super localizedStringForKey:key value:value table:tableName];
  6. }
  7. }
  8. + (NSBundle *)cl_mainBundle {
  9. if ([NSBundle currentLanguage].length) {
  10. NSString *path = [[NSBundle mainBundle] pathForResource:[NSBundle currentLanguage] ofType:@"lproj"];
  11. if (path.length) {
  12. return [NSBundle bundleWithPath:path];
  13. }
  14. }
  15. return nil;
  16. }
  17. + (NSString *)currentLanguage {
  18. return [CLLanguageManager userLanguage] ? : [NSLocale preferredLanguages].firstObject;
  19. }
  20. 复制代码
3.语言管理类

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

  1. + (void)setUserLanguage:(NSString *)userLanguage {
  2. //跟随手机系统
  3. if (!userLanguage.length) {
  4. [self resetSystemLanguage];
  5. return;
  6. }
  7. //用户自定义
  8. [[NSUserDefaults standardUserDefaults] setValue:userLanguage forKey:CLUserLanguageKey];
  9. [[NSUserDefaults standardUserDefaults] setValue:@[userLanguage] forKey:@"AppleLanguages"];
  10. [[NSUserDefaults standardUserDefaults] synchronize];
  11. }
  12. + (NSString *)userLanguage {
  13. return [[NSUserDefaults standardUserDefaults] valueForKey:CLUserLanguageKey];
  14. }
  15. /**
  16. 重置系统语言
  17. */
  18. + (void)resetSystemLanguage {
  19. [[NSUserDefaults standardUserDefaults] removeObjectForKey:CLUserLanguageKey];
  20. [[NSUserDefaults standardUserDefaults] setValue:nil forKey:@"AppleLanguages"];
  21. [[NSUserDefaults standardUserDefaults] synchronize];
  22. }
  23. 复制代码
4.切换根控制器来切换语言

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

  1. [CLLanguageManager setUserLanguage:@"en"];
  2. CLTabbarController *tabbarController = [[CLTabbarController alloc] init];
  3. tabbarController.selectedIndex = 3;
  4. UINavigationController *navigationController = tabbarController.selectedViewController;
  5. NSMutableArray *viewControllers = navigationController.viewControllers.mutableCopy;
  6. //取出我的页面,提前加载,解决返回按钮不变化
  7. CLMyController *me = (CLMyController *)[viewControllers firstObject];
  8. [me loadViewIfNeeded];
  9. //新建设置语言页面
  10. CLChangeLanguageController *languageController = [[CLChangeLanguageController alloc] init];
  11. languageController.hidesBottomBarWhenPushed = YES;
  12. [viewControllers addObject:languageController];
  13. //解决奇怪的动画bug。
  14. dispatch_async(dispatch_get_main_queue(), ^{
  15. [UIApplication sharedApplication].keyWindow.rootViewController = tabbarController;
  16. navigationController.viewControllers = viewControllers;
  17. CLLog(@"已切换到语言 %@", [NSBundle currentLanguage]);
  18. });
  19. 复制代码

效果图

总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/196681
推荐阅读
相关标签
  

闽ICP备14008679号