原理:
NSLocalizedStringFromTableInBundle(key, table, _bundle, nil)
从CSDN下载【iOS APP 内的国际化切换】demo源码:https://download.csdn.net/download/u011018979/19089505
在这里插入图片描述
选 make Localize代表会将Localizable.strings加入到英语的本地化文件夹en.lproj中去
在这里插入图片描述
Localizable.strings(English)对应en.lproj文件夹中的Localizable.strings文件 Localizable.strings(Chinese)对应zh-Hans.lproj文件夹中的Localizable.strings文件
en.lproj/Localizable.strings
static NSString * const kSystem = @"SystemDefault";
static NSString * const kCH = @"zh-Hans";
static NSString * const kEN = @"en";
static NSString * const kProj = @"lproj";
static NSString * const kLanguageSet = @"kLanguageSet";
"Connected" = "Connected";
"Tip"="Tip";
zh-Hans.lproj/Localizable.strings
"Connected" = "已连接";
"Tip"="提示";
在这里插入图片描述
#define NSLocalizedString(key, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \
[NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) \
[bundle localizedStringForKey:(key) value:(val) table:(tbl)]
//程序的本地化,引用国际化的文件
#define QCTLocal(x, ...) HZLocalizedString(x, nil)
#define HZLocalizedString(key, comment) HZLocalizedStringFromTable(key, @"Localizable", nil)
#define HZLocalizedStringFromTable(key, tbl, comment) [[HZLanguageManager defaultManager] stringWithKey:key table:tbl]
/**
@param key <#key description#>
@param table Localizable
@return <#return value description#>
*/
- (NSString *)stringWithKey:(NSString *)key table:(NSString *)table
{
//假如为跟随系统
if (self.languageType==HZLanguageTypeSystem) {
return NSLocalizedString(key, nil);
}
//返回对应国际化文字
if (_bundle) {
return NSLocalizedStringFromTableInBundle(key, table, _bundle, nil);
}
return NSLocalizedStringFromTable(key, table, nil);
}
// 使用QCTLocal读取本地化字符串
[LBAlertController showAlertTitle:QCTLocal(@"tips") content:QCTLocal(@"str_cann_printer") cancelString:QCTLocal(@"cancel") cancleBlock:nil sureString:QCTLocal(@"sure") sureBlock:^{
如果没有对字符串进行本地化 或者 找不到key对应的值,NSLocalizedString将直接返回key这个字符串
重置TableBundle
- (void)resetBundle{
NSLog(@"resetBundle:%@",_languageString);
if ([_languageString isEqualToString:kEN] || [_languageString isEqualToString:kCH]) {
NSString *path = [[NSBundle mainBundle] pathForResource:_languageString ofType:kProj];
self.bundle = [NSBundle bundleWithPath:path];
}
}
由于审核时境外IP无法访问,决定去掉英文版本。
https://blog.csdn.net/z929118967/article/details/89277538
// 由于审核时,境外IP无法访问,决定去掉英文版本
- (void)setLanguageType:(HZLanguageType)languageType{
//HZLanguageTypeChineseSimple
languageType =HZLanguageTypeChineseSimple;
_languageString = kCH;//强制为中文
_languageType =languageType;
}
// 中英文切换
- (void)changeLanguageType:(HZLanguageType)type;
{
if (self.currentLanguageType == type) {
return;
}
self.languageType = type;
switch (self.languageType) {
case HZLanguageTypeSystem:
self.languageString=kSystem;
break;
case HZLanguageTypeEnglish:
self.languageString = kEN;
break;
case HZLanguageTypeChineseSimple:
self.languageString = kCH;
break;
}
//bundle 设置
[self resetBundle];
//设置语言,并作记录保存
[[NSUserDefaults standardUserDefaults] setObject:_languageString forKey:kLanguageSet];
[[NSUserDefaults standardUserDefaults] synchronize];
//使用通知更改文字 [[NSNotificationCenter defaultCenter] postNotificationName:kNoticeLanguageChange object:nil];
}
对于在中英文语法的区别,在本地化字符串的时候,我们常常需要调整stringWithFormat的参数顺序
文章:https://kunnan.blog.csdn.net/article/details/108793150 原理:在%和@中间加上数值
,2$),数字代表参数的顺序
"FORMAT" = "I am %2$@ from '%1$@'";
从CSDN下载【iOS APP 内的国际化切换】demo源码:https://download.csdn.net/download/u011018979/19089505
#import <Foundation/Foundation.h>
#define HZLocalizedString(key, comment) HZLocalizedStringFromTable(key, @"Localizable", nil)
#define HZLocalizedStringFromTable(key, tbl, comment) [[HZLanguageManager defaultManager] stringWithKey:key table:tbl]
static NSString * const kNoticeLanguageChange = @"kNoticeLanguageChange";
typedef NS_ENUM(NSUInteger, HZLanguageType) {
HZLanguageTypeSystem,
HZLanguageTypeEnglish,
HZLanguageTypeChineseSimple,
};
@interface HZLanguageManager : NSObject
@property (nonatomic, assign, getter=currentLanguageType) HZLanguageType languageType;
+ (instancetype)defaultManager;
- (void)changeLanguageType:(HZLanguageType)type;
- (NSString *)stringWithKey:(NSString *)key table:(NSString *)table;
- (HZLanguageType)currentLanguage;
+ (BOOL )isEN;
static NSString * const kSystem = @"SystemDefault";
static NSString * const kCH = @"zh-Hans";
static NSString * const kEN = @"en";
static NSString * const kProj = @"lproj";
static NSString * const kLanguageSet = @"kLanguageSet";
@interface HZLanguageManager()
@property (nonatomic, strong) NSBundle *bundle;
@property (nonatomic, strong) NSString *languageString;
@end
@implementation HZLanguageManager
+ (instancetype)defaultManager
{
static dispatch_once_t onceToken;
static HZLanguageManager *manager;
dispatch_once(&onceToken, ^{
if (!manager) {
manager = [[HZLanguageManager alloc] init];
}
});
return manager;
}
- (instancetype)init
{
self = [super init];
if (!self) {
return nil;
}
//取字段看是哪种语言
NSString *tempStr = [[NSUserDefaults standardUserDefaults] objectForKey:kLanguageSet];
// NSString *path;
//假如用户没有设置过语言
if (!tempStr) {
tempStr=kSystem;
}
self.languageString = tempStr;
if ([self.languageString isEqualToString:kCH]) {//为中文
self.languageType = HZLanguageTypeChineseSimple;
}else if ([self.languageString isEqualToString:kEN]) {//为英文
self.languageType = HZLanguageTypeEnglish;
}else if([self.languageString isEqualToString:kSystem]){//为系统默认
self.languageType= HZLanguageTypeSystem;
if([self isENLanguage]){//HZLanguageManager
self.languageType = HZLanguageTypeEnglish;
}else{
self.languageType = HZLanguageTypeChineseSimple;
}
}
if ([_languageString isEqualToString:kEN] || [_languageString isEqualToString:kCH]) {
NSString *path = [[NSBundle mainBundle] pathForResource:_languageString ofType:kProj];
self.bundle = [NSBundle bundleWithPath:path];
}
NSLog(@"当前的语言 HZLanguageTypeSystem HZLanguageTypeEnglish HZLanguageTypeChineseSimple:%lu",(unsigned long)self.languageType);
return self;
}
- (void)changeLanguageType:(HZLanguageType)type;
{
if (self.currentLanguageType == type) {
return;
}
_languageType = type;
switch (type) {
case HZLanguageTypeSystem:
self.languageString=kSystem;
break;
case HZLanguageTypeEnglish:
self.languageString = kEN;
break;
case HZLanguageTypeChineseSimple:
self.languageString = kCH;
break;
}
//bundle 设置
[self resetBundle];
//设置语言,并作记录保存
[[NSUserDefaults standardUserDefaults] setObject:_languageString forKey:kLanguageSet];
[[NSUserDefaults standardUserDefaults] synchronize];
//使用通知更改文字 [[NSNotificationCenter defaultCenter] postNotificationName:kNoticeLanguageChange object:nil];
}
- (void)resetBundle{
if ([_languageString isEqualToString:kEN] || [_languageString isEqualToString:kCH]) {
NSString *path = [[NSBundle mainBundle] pathForResource:_languageString ofType:kProj];
self.bundle = [NSBundle bundleWithPath:path];
}
}
- (NSString *)stringWithKey:(NSString *)key table:(NSString *)table
{
//假如为跟随系统
if (self.languageType==HZLanguageTypeSystem) {
return NSLocalizedString(key, nil);
}
//返回对应国际化文字
if (_bundle) {
return NSLocalizedStringFromTableInBundle(key, table, _bundle, nil);
}
return NSLocalizedStringFromTable(key, table, nil);
}
-(HZLanguageType)currentLanguage{
//获取当前语言
// NSString *tempStr = [[NSUserDefaults standardUserDefaults] objectForKey:kLanguageSet];
// if ([tempStr rangeOfString:@"zh"].length) {
//// tempStr = kCH;
// return HZLanguageTypeChineseSimple;
// }else if([tempStr isEqualToString:kEN]){
//// tempStr = kEN;
// return HZLanguageTypeEnglish;
// }else {//if([tempStr isEqualToString:kSystem])
//
// return HZLanguageTypeSystem;
// }
return self.languageType;
}
+ (NSArray *)english {
return @[@"en", @"en-CN"];
}
+ (NSArray *)chineseHans {
return @[@"zh-Hans", @"zh-Hans-CN"];
}
+ (NSArray *)chineseHant {
return @[@"zh-Hant", @"zh-Hant-CN"];
}
/**
(lldb) po [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"]
<__NSCFArray 0x2833357a0>(
zh-Hans-AM,
en-AM,
en-GB,
ru-AM,
zh-Hant-AM,
zh-Hant-HK
)
第一个就是用户设置的语言
@return
*/
- (BOOL )isENLanguage {
// NSString *language = [[NSUserDefaults standardUserDefaults] objectForKey:GHLLanguageKey];
// if (){
// if ([HZLanguageManager defaultManager].currentLanguage==HZLanguageTypeEnglish) {
if (self.currentLanguage == HZLanguageTypeEnglish) {
return YES;
}
// if () {
NSArray *languages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
NSString *language = languages.firstObject;
// }
// if([[HZLanguageManager chineseHans] containsObject:language] || [[HZLanguageManager chineseHant] containsObject:language] ){
if([language containsString:@"zh-Hans"] || [language containsString:@"zh-Hant"] ){
return NO;
}else{
return YES;
}
}
+ (BOOL )isEN{
if([HZLanguageManager defaultManager].currentLanguage == HZLanguageTypeEnglish ){
// make.width.mas_equalTo(kAdjustRatio(73 * 3));
return YES;
}else{
// make.width.mas_equalTo(kAdjustRatio(50 * 3));
// make.left.equalTo(weakSelf.contentView).offset(kAdjustRatio(20));
// make.right.equalTo(weakSelf.contentView).offset(- kAdjustRatio(20));
//
return NO;
}
}
@end
/consts/Localizable/en.lproj/Localizable.strings
文本内容太长了。 会导致key 失效。
新增一个table来存储,解析的时候从两个文件查找。
new file: retail/retail/class/consts/Localizable/en.lproj/Localizable1.strings
new file: retail/retail/class/consts/Localizable/zh-Hans.lproj/Localizable1.strings
如果你的字符串资源文件名不是Localizable.strings,如KN.strings,那么你就得使用NSLocalizedStringFromTable()、NSLocalizedStringFromTableInBundle来读取本地化字符串:
- (NSString *)stringWithKey:(NSString *)key table:(NSString *)table
{
//假如为跟随系统
if (self.languageType==HZLanguageTypeSystem) {
return NSLocalizedString(key, nil);
}
//返回对应国际化文字
if (_bundle) {// 修改成为,从另外一个文件找,先从文件找,如果找不到就从文件二找。
//NSLocalizedStringFromTableInBundleWithKey
return [self NSLocalizedStringFromTableInBundleWithKey:key table:table];
return NSLocalizedStringFromTableInBundle(key, table, _bundle, nil);
}
return NSLocalizedStringFromTable(key, table, nil);
}
/**
如果你的字符串资源文件名不是Localizable.strings,如KN.strings,那么你就得使用NSLocalizedStringFromTable()来读取本地化字符串:
*/
//{// 修改成为,从另外一个文件找,先从文件找,如果找不到就从文件二找。
- (NSString*)NSLocalizedStringFromTableInBundleWithKey:(NSString *)key table:(NSString *)table{
NSString* tmp = key;
if(_bundle){
tmp =NSLocalizedStringFromTableInBundle(key, table, _bundle, nil);
if([tmp isEqualToString:key]){
// 继续从备份表查找
NSLog(@"开始从Localizable1 找key:%@", tmp);
tmp =NSLocalizedStringFromTableInBundle(key, @"Localizable1", _bundle, nil);
// NSLog([NSString stringWithFormat:@"结束从Localizable1 找key:%@",tmp]);
NSLog(@"结束从Localizable1 找key:%@", tmp);
}
}
return tmp;
}
在这里插入图片描述
Info.plist中的CFBundleDisplayName的key决定了应用程序的名称
"NSMicrophoneUsageDescription" = "Allow this app to use your microphone for decibel detection and sound recording; audio is recorded locally only and is not sent to anyone, only for decibel detection and sound variation.";
iOS《用户协议及隐私政策》弹框(包含超链接属性)【本文包含完整demo源码,demo支持中英文切换】 | 蓄力计划
https://kunnan.blog.csdn.net/article/details/103902362
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if([LanguageManager isEN] ){
// _titleLab.font = kPingFangFont(10);
[[LanguageManager defaultManager] changeLanguageType: HZLanguageTypeEnglish];
NSLog(@"当前位英文版本");
}else{
// _titleLab.font = kPingFangFont(12);
NSLog(@"当前位中文版本");
[[HZLanguageManager defaultManager] changeLanguageType: HZLanguageTypeChineseSimple];
}
}
https://github.com/zhangkn/LanguageManager/tree/main/iUIPageControlFix4iOS14/LanguageManager
处理切换中英文语言的动作事件
- (UILabel *)languageLab{
if (!_languageLab) {
_languageLab = [[UILabel alloc]init];
_languageLab.textColor = rgb(51,51,51);
_languageLab.font = kBoldFont(15);
_languageLab.textAlignment = NSTextAlignmentRight;
// 根据配置进行显示
// typedef NS_ENUM(NSUInteger, HZLanguageType) {
// HZLanguageTypeSystem,
// HZLanguageTypeEnglish,
// HZLanguageTypeChineseSimple,
// };
// 获取配置信息
//设置选中的语言
if ([HZLanguageManager defaultManager].currentLanguage==HZLanguageTypeSystem) {
// self.seletedIndex=@0;
}
else if ([HZLanguageManager defaultManager].currentLanguage==HZLanguageTypeChineseSimple) {
// self.seletedIndex=@1;
// _languageLab.text = @"";
_languageLab.text = @"English";
}
else if ([HZLanguageManager defaultManager].currentLanguage==HZLanguageTypeEnglish) {
// self.seletedIndex=@2;
_languageLab.text = @"简体中文";
}else{
// _languageLab.text = @"简体中文";
}
//
// ti ti阿佳
//
_languageLab.userInteractionEnabled = YES;
[self addSubview:_languageLab];
__weak __typeof__(self) weakSelf = self;
[_languageLab mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(weakSelf).offset(36);
make.right.equalTo(weakSelf).offset(-kAdjustRatio(16));
make.size.mas_equalTo(CGSizeMake(kAdjustRatio(100), kAdjustRatio(40)));
}];
UITapGestureRecognizer *cutTap = [[UITapGestureRecognizer alloc] init];
// __weak __typeof__(self) weakSelf = self;
[[cutTap rac_gestureSignal] subscribeNext:^(id x) {
switch ([HZLanguageManager defaultManager].currentLanguage) {
case HZLanguageTypeSystem:
{
}
break;
case HZLanguageTypeEnglish:
{
[[HZLanguageManager defaultManager] changeLanguageType: HZLanguageTypeChineseSimple];
weakSelf.languageLab.text = @"简体中文";
}
break;
case HZLanguageTypeChineseSimple:
{
[[HZLanguageManager defaultManager] changeLanguageType: HZLanguageTypeEnglish];
weakSelf.languageLab.text = @"English";
}
break;
default:
{
}
break;
}
[ AccountLoginView rootViewController4nil];
}];
[_languageLab addGestureRecognizer:cutTap];
}
return _languageLab;
}
+ (void) rootViewController4nil{
//销毁 root
UIWindow *oldWindow=[UIApplication sharedApplication].keyWindow;
oldWindow.rootViewController=nil;
//新 root
UIWindow *newWindow = [UIApplication sharedApplication].keyWindow;
AccountLoginViewController *VC = [[AccountLoginViewController alloc]init];
HWNavigationController *NA = [[HWNavigationController alloc]initWithRootViewController:VC];
[AccountLoginView restoreRootViewController:NA newWindow:newWindow];
}
/**
UIModalTransitionStyleCoverVertical = 0, //从下到上盖上进入
UIModalTransitionStyleFlipHorizontal, //水平翻转
UIModalTransitionStyleCrossDissolve, //渐变出现
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
UIModalTransitionStylePartialCurl, //类似翻页的卷曲
@param rootViewController <#rootViewController description#>
@param newWindow <#newWindow description#>
https://github.com/codeRiding/CRProject/blob/165886b8426fa43b52e76e659b8e18496e2fa8c8/CRProject/Classes/Expand/Tool/CRChangeVC.m
*/
+ (void)restoreRootViewController:(UIViewController *)rootViewController newWindow:(UIWindow*)newWindow
{
typedef void (^Animation)(void);
UIWindow* window = newWindow;
//
rootViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
//UIModalPresentationPopover
//UIModalPresentationNone
// rootViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;//UIModalPresentationOverFullScreen
// UIModalTransitionStyleCoverVertical = 0,
// UIModalTransitionStyleFlipHorizontal __TVOS_PROHIBITED,
// UIModalTransitionStyleCrossDissolve,
// UIModalTransitionStylePartialCurl
// rootViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
Animation animation = ^{
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
// [UIApplication sharedApplication].keyWindow.rootViewController = rootViewController;
[newWindow switchWithRootViewController:rootViewController];
[UIView setAnimationsEnabled:oldState];
};
//
[UIView transitionWithView:window
duration:0.5f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:animation
completion:nil];
}
对于在中英文语法的区别,在本地化字符串的时候,我们常常需要调整stringWithFormat的参数顺序
原理:在%和@中间加上数值(1,2$),数字代表参数的顺序 文章:https://blog.csdn.net/z929118967/article/details/108793150
https://kunnan.blog.csdn.net/article/details/112865806
https://blog.csdn.net/z929118967/article/details/104572619