一、准备工作
1、在Project中的info新增需要支持的语言

2、新增.string语言文件用于文本替换,在文件中写入,比如繁体中写入 "用户协议" = "用戶協議";

二、新建语言控制类代码
1、LanguageManager.h
#import <Foundation/Foundation.h>
extern NSString * const LanguageDidChangeNotification;
typedef enum : NSUInteger {
RegionTypeMainlandChina,
RegionTypeHongKong,
RegionTypeMacau,
} RegionType;
typedef enum : NSUInteger {
LanguageTypeSimplifiedChinese,
LanguageTypeTraditionalChinese,
LanguageTypeEnglish,
} LanguageType;
@interface LanguageManager : NSObject
+ (instancetype)sharedManager;
/// 设置app语言
/// - Parameter language: 语言代码 如 @"en", @"zh-Hans"
- (void)setLanguage:(NSString *)language;
/// 获取系统语言转换后的字符串数组
/// - Parameter array: 字符串数组
- (NSMutableArray *)localizedArray:(NSArray *)array;
/// 获取系统语言转换后的字符串
/// - Parameter key: 字符串key
- (NSString *)localizedStringForKey:(NSString *)key;
/// 获取当前语言
- (NSString *)currentLanguage;
/// 获取用户系统设置地区
@property (nonatomic, assign) RegionType regionType;
/// 获取用户系统设置语言,只做获取不做设置
@property (nonatomic, assign) LanguageType languageType;
@end
2、LanguageManager.m
#import "LanguageManager.h"
#define kAppLanguage @"AppLanguage"
NSString * const LanguageDidChangeNotification = @"LanguageDidChangeNotification";
@interface LanguageManager ()
@property (nonatomic, strong) NSBundle *bundle;
@end
@implementation LanguageManager
+ (instancetype)sharedManager {
static LanguageManager *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[LanguageManager alloc] init];
});
return instance;
}
- (instancetype)init {
if (self = [super init]) {
NSString *language = [[NSUserDefaults standardUserDefaults] objectForKey:kAppLanguage];
if (!language) language = [NSLocale preferredLanguages].firstObject;
[self updateBundleWithLanguage:language];
}
return self;
}
- (void)setLanguage:(NSString *)language {
[[NSUserDefaults standardUserDefaults] setObject:language forKey:kAppLanguage];
[[NSUserDefaults standardUserDefaults] synchronize];
[self updateBundleWithLanguage:language];
// 保存语言到用户偏好设置
kUser.languageCode = language;
// 发送语言改变通知
[[NSNotificationCenter defaultCenter] postNotificationName:LanguageDidChangeNotification object:nil];
}
- (NSMutableArray *)localizedArray:(NSArray *)array {
NSMutableArray *localized = [NSMutableArray array];
for (NSString *key in array) {
NSString *text = [self localizedStringForKey:key];
[localized addObject:text];
}
return localized;
}
- (void)updateBundleWithLanguage:(NSString *)language {
NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"];
if (path) {
self.bundle = [NSBundle bundleWithPath:path];
} else {
self.bundle = [NSBundle mainBundle];
}
}
- (NSString *)localizedStringForKey:(NSString *)key {
return [self.bundle localizedStringForKey:key value:nil table:@"Localizable"];
}
- (NSString *)currentLanguage {
return [[NSUserDefaults standardUserDefaults] objectForKey:kAppLanguage];
}
- (RegionType)regionType {
NSString *countryCode = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
if ([countryCode isEqualToString:@"CN"]) {
return RegionTypeMainlandChina;
} else if ([countryCode isEqualToString:@"HK"]) {
return RegionTypeHongKong;
} else if ([countryCode isEqualToString:@"MO"]) {
return RegionTypeMacau;
} else {
return RegionTypeMainlandChina;
}
}
- (LanguageType)languageType {
NSString *languageCode = [self currentLanguage];
if ([languageCode isEqualToString:@"zh-Hans"]) {
return LanguageTypeSimplifiedChinese;
} else if ([languageCode isEqualToString:@"zh-Hant"]) {
return LanguageTypeTraditionalChinese;
} else if ([languageCode isEqualToString:@"en"]) {
return LanguageTypeEnglish;
} else {
return LanguageTypeSimplifiedChinese;
}
}
@end
3、ViewController中切换
可以重新加载VC,也可以自定义一个方法切换,下面仅展示重新加载
在VC中写通知接收,tabbar文本也需要更新,根据需求来
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(rebuildSelfForLanguageChange)
name:LanguageDidChangeNotification
object:nil];
- (void)rebuildSelfForLanguageChange {
UINavigationController *nav = self.navigationController;
Class cls = [self class];
UIViewController *newVC = [[cls alloc] init];
// 保留 TabBarItem
newVC.tabBarItem = self.tabBarItem;
NSMutableArray *controllers = [nav.viewControllers mutableCopy];
NSUInteger idx = [controllers indexOfObject:self];
controllers[idx] = newVC;
[nav setViewControllers:controllers animated:NO];
}
如果是在没有tabbar的子页面可以这样初始化,避免重新加载后后tabbar突然出现
- (void)rebuildSelfForLanguageChange {
UINavigationController *nav = self.navigationController;
Class cls = [self class];
UIViewController *newVC = [[cls alloc] init];
// 保留 hidesBottomBarWhenPushed
newVC.hidesBottomBarWhenPushed = self.hidesBottomBarWhenPushed;
NSMutableArray *controllers = [nav.viewControllers mutableCopy];
NSUInteger idx = [controllers indexOfObject:self];
controllers[idx] = newVC;
[nav setViewControllers:controllers animated:NO];
}
4、调用示例
//可以在AppDelegate中设置初始化语言
- (void)initWindow {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = kWhiteColor;
[self.window makeKeyAndVisible];
kApplication.statusBarHidden = NO;
if (kUser.languageCode.length == 0) {
NSString *systemLanguage = [NSLocale preferredLanguages].firstObject; // e.g., "zh-Hant-CN"
NSString *appLanguage = @"en"; // 默认英文
if ([systemLanguage hasPrefix:@"zh"]) {
if ([systemLanguage containsString:@"Hant"]) {
appLanguage = @"zh-Hant"; // 繁体
} else {
appLanguage = @"zh-Hans"; // 简体
}
} else if ([systemLanguage hasPrefix:@"en"]) {
appLanguage = @"en"; // 英文
}
// 设置语言
[[LanguageManager sharedManager] setLanguage:appLanguage];
}
}
//设置好语言之后可以通过这种方式自动匹配繁体或者简体或者英文
_tipText.text = [[LanguageManager sharedManager] localizedStringForKey:@"验证码登录"];