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]);
});

效果图

iOS开发教程之APP内部切换语言的实现方法

总结

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

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...