iOS app语言切换
一、准备工作
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;@end2、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;}
}@end3、ViewController中切换
可以重新加载VC,也可以自定义一个方法切换,下面仅展示重新加载
在VC中写通知接收,tabbar文本也需要更新,根据需求来
[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(rebuildSelfForLanguageChange)name:LanguageDidChangeNotificationobject:nil];
- (void)rebuildSelfForLanguageChange {UINavigationController *nav = self.navigationController;Class cls = [self class];UIViewController *newVC = [[cls alloc] init];// 保留 TabBarItemnewVC.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];// 保留 hidesBottomBarWhenPushednewVC.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:@"验证码登录"];