iOS实践——语言切换

ps:有一种需求,叫做app内语言切换,我的这个版本,代码更具体一些,请勿喷
ps:哎,有一种需求,叫做网络下载语言包进行多语言切换,目的是再添加语言支持,不用另发版本,此功能下回分析~~

iOS实践——语言切换_第1张图片
语言切换.PNG

0.文件结构介绍

InternationalControl           ——控制切换语言工具类(关键)
ALCommentMethod                ——便捷设置文字工具类
DLLanguageObject               ——语言附加信息实体类,充当数据载体功能
ALChooseLanguageVC             ——选择语言具体控制器,业务具体相关,仅做参考,请自行实现

1.相关宏

1)便捷切换文字

#define DLLocal(localName) [ALCommentMethod localizationString:localName]

2)相关通知

//1.添加通知
#define  ADDChangeLanguageNotification            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeLanguage) name:AL_NOTIFICATION_CHANGE_LANGUAGE object:nil]

//2.发送通知
#define  POSTChangeLanguageInfoNotification       [[NSNotificationCenter defaultCenter] postNotificationMainThreadName:AL_NOTIFICATION_CHANGE_LANGUAGE object:nil]

//3.移除通知
#define  REMOVEUpdateUserInfoNotification [[NSNotificationCenter defaultCenter] removeObserver:self]

2.接受通知后进行刷新文字(此处处理方式,总觉着不够技术含量,若有更好的方式,请告知)

#pragma mark - 初始化
- (void)initToolView{
    //...
    self.bottomToolView = bottomToolView;
    ADDChangeLanguageNotification;//添加通知
}

- (void)changeLanguage{
    //重新刷新一下界面文字
    self.appName.text = DLLocal(@"bottom_tool_choose_app");
    [self setNeedsLayout];
}

- (void)dealloc{
    REMOVEUpdateUserInfoNotification;//移除通知
}

3.代码

1) InternationalControl 控制切换语言工具类(关键)

#import 

@class DLLanguageObject;

@interface InternationalControl : NSObject
+(NSBundle *)bundle;/**< 获取当前资源文件 */

+(void)initUserLanguage;/**< 初始化语言文件 */
+(NSString *)userLanguage;/**< 获取应用当前语言 */
+(DLLanguageObject *)currentLanguage;/**< 获取应用当前语言 */
+(NSString *)userLanguageEnOrZh; /**< 返回 en 或者 zh */

#pragma mark - 定制语言
+(void)setUserlanguage:(DLLanguageObject *)lanObj;/**< 设置当前语言 */

+ (NSString *)currentSysLanguage;/**< 获取当前系统语言 */
@end
#import "InternationalControl.h"
#import "DLLanguageObject.h"

#define kUserLanguageObject @"userLanguageObject"
#define kAppleLanguages @"AppleLanguages"

@implementation InternationalControl

static NSBundle *bundle = nil;
static DLLanguageObject *langObj = nil;

+ ( NSBundle * )bundle{
    return bundle;
}

+(void)initUserLanguage{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSData *lanDataBox = [def valueForKey:kUserLanguageObject];
    langObj = [NSKeyedUnarchiver unarchiveObjectWithData:lanDataBox];
    
    if(!langObj){
        //获取系统当前语言版本(中文zh-Hans,英文en)
        NSArray* languages = [def objectForKey:kAppleLanguages];
        NSString *current = [languages objectAtIndex:0];
        
        if ([current isEqualToString:@"zh-Hans-CN"]) {
            langObj = [DLLanguageObject languageType:DLLanguageTypeCn];
        }else{
            langObj = [DLLanguageObject languageType:DLLanguageTypeEn];
        }
        
        NSData *lanData = [NSKeyedArchiver archivedDataWithRootObject:langObj];
        [def setObject:lanData forKey:kUserLanguageObject];
        [def synchronize];//持久化,不加的话不会保存
    }
    
    //获取文件路径
    NSString *path = [[NSBundle mainBundle] pathForResource:langObj.lanCode ofType:@"lproj"];
    bundle = [NSBundle bundleWithPath:path];//生成bundle
}

#pragma mark - 定制语言
+(void)setUserlanguage:(DLLanguageObject *)lanObj{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    //1.第一步改变bundle的值
    NSString *path = [[NSBundle mainBundle] pathForResource:lanObj.lanCode ofType:@"lproj" ];
    bundle = [NSBundle bundleWithPath:path];
    
    //2.改变记录
    langObj = lanObj;
    
    //3.持久化
    NSData *lanData = [NSKeyedArchiver archivedDataWithRootObject:lanObj];
    [def setObject:lanData forKey:kUserLanguageObject];
    [def synchronize];//持久化,不加的话不会保存
}

+(NSString *)userLanguageEnOrZh{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSData *lanDataBox = [def valueForKey:kUserLanguageObject];
    DLLanguageObject *lanObj = [NSKeyedUnarchiver unarchiveObjectWithData:lanDataBox];
    if ([lanObj.lanCode isEqualToString:@"en"]){
        return @"en";
    } else{
        return @"zh";
    }
}

+(NSString *)userLanguage{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSData *lanDataBox = [def valueForKey:kUserLanguageObject];
    DLLanguageObject *lanObj = [NSKeyedUnarchiver unarchiveObjectWithData:lanDataBox];
    return lanObj.lanCode;
}

+(DLLanguageObject *)currentLanguage{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSData *lanDataBox = [def valueForKey:kUserLanguageObject];
    DLLanguageObject *lanObj = [NSKeyedUnarchiver unarchiveObjectWithData:lanDataBox];
    return lanObj;
}

+ (NSString *)currentSysLanguage{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    NSArray* languages = [def objectForKey:kAppleLanguages];
    return [languages objectAtIndex:0];
}
@end

2)ALCommentMethod 便捷设置文字工具类

#import 
#import "InternationalControl.h"

@interface ALCommentMethod : NSObject
+ (NSString *)localizationString:(NSString *)key;
@end
#import "ALCommentMethod.h"
@implementation ALCommentMethod
+ (NSString *)localizationString:(NSString *)key{
    NSBundle *langBundle = [InternationalControl bundle];
    NSString *str = [langBundle localizedStringForKey:key value:@"" table:nil];
    return str;
}
@end

3)DLLanguageObject 语言附加信息实体类,充当数据载体功能

#import 

typedef NS_ENUM(NSUInteger,DLLanguageType){
    DLLanguageTypeEn = 0,
    DLLanguageTypeCn
};
@interface DLLanguageObject : NSObject

@property (nonatomic,assign) DLLanguageType langType;/**< 语言类型 */
@property (nonatomic,strong) NSString *lanCode;/**< 语言代码字符串 */
@property (nonatomic,strong) NSString *titile;/**< 标题 */
@property (nonatomic,strong) NSString *subTitle;/**< 子标题  */
@property (nonatomic,assign) BOOL isSelected;/**< 选中与否 */

#pragma mark - 快速创建
+ (instancetype)languageType:(DLLanguageType)langType;
- (instancetype)initWithLanType:(DLLanguageType)langType;
@end
#import "DLLanguageObject.h"

#define kEnLan @"en"
#define kCnLan @"zh-Hans"

@implementation DLLanguageObject

+ (instancetype)languageType:(DLLanguageType)langType{
    return [[self alloc] initWithLanType:langType];
}


- (instancetype)initWithLanType:(DLLanguageType)langType{
    self = [super init];
    if (self) {
        self.langType = langType;
    }
    return self;
}

- (void)setLangType:(DLLanguageType)langType{
    _langType = langType;
    switch (langType) {
        case DLLanguageTypeEn:{
            _lanCode = kEnLan;
            self.titile = @"English";
            self.subTitle = @"English";
            break;
        }
        case DLLanguageTypeCn:{
            _lanCode = kCnLan;
            self.titile = @"简体中文";
            self.subTitle = @"Chinese,Simpified";
            break;
        }
            
        default:
            break;
    }
}

#pragma mark -
//This is important to for saving the alarm object in user defaults
-(void)encodeWithCoder:(NSCoder *)encoder{
    [encoder encodeInteger:self.langType forKey:@"langType"];
    [encoder encodeObject:self.lanCode forKey:@"lanCode"];
    [encoder encodeObject:self.titile forKey:@"titile"];
    [encoder encodeObject:self.subTitle forKey:@"subTitle"];
    [encoder encodeBool:self.isSelected forKey:@"isSelected"];
}

//This is important to for loading the alarm object from user defaults
-(id)initWithCoder:(NSCoder *)decoder{
    self.langType = [decoder decodeIntegerForKey:@"langType"];
    self.lanCode = [decoder decodeObjectForKey:@"lanCode"];
    self.titile = [decoder decodeObjectForKey:@"titile"];
    self.subTitle = [decoder decodeObjectForKey:@"subTitle"];
    self.isSelected = [decoder decodeBoolForKey:@"isSelected"];
    return self;
}
@end

4)ALChooseLanguageVC 选择语言具体控制器,业务具体相关,仅做参考,请自行实现

#import "ALChooseLanguageVC.h"
#import "ALLanguageCell.h"
#import "DLLanguageObject.h"
#import "InternationalControl.h"

@interface ALChooseLanguageVC ()
@property (nonatomic,strong) NSMutableArray *dataList;/**< 数据源 */
@property (nonatomic,strong) DLLanguageObject *selectedLan;/**< 选中的语言 */
@end

@implementation ALChooseLanguageVC

- (NSMutableArray *)dataList{
    if (!_dataList) {
        _dataList = [NSMutableArray array];
        
        DLLanguageObject *lanEn = [DLLanguageObject languageType:DLLanguageTypeEn];
        DLLanguageObject *lanCn = [DLLanguageObject languageType:DLLanguageTypeCn];
        
        [_dataList addObject:lanEn];
        [_dataList addObject:lanCn];
    }
    return _dataList;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = DLLocal(@"language_chage_title");
    [self settingRightButton];
    
    
    NSInteger index = 0;
    for (DLLanguageObject *lanObj in self.dataList) {
        DLLanguageObject *currentLanguage = [InternationalControl currentLanguage];
        if ([lanObj.lanCode isEqualToString:currentLanguage.lanCode]) {
            currentLanguage.isSelected = YES;
            self.selectedLan = currentLanguage;
            break;
        }
        index++;
    }
    
    [self.dataList replaceObjectAtIndex:index withObject:self.selectedLan];
    [self.tableView reloadData];
}

- (void)settingRightButton{
    [self replaceRightBarButtonItemWithTitle:UBTLocalizedString(@"phone_search_sure") image:nil target:self action:@selector(comfirmSettingLanguage)];
}

- (void)comfirmSettingLanguage{
    [InternationalControl setUserlanguage:self.selectedLan];
    POSTChangeLanguageInfoNotification;
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataList.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ALLanguageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ALLanguageCell"];
    cell.lanObj = [self.dataList objectAtIndexWithExamine:indexPath.row];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    self.selectedLan.isSelected = NO;
    DLLanguageObject *lan = [self.dataList objectAtIndexWithExamine:indexPath.row];
    lan.isSelected = YES;
    self.selectedLan = lan;
    [self.tableView reloadData];
}

@end

参考:iOS应用内部切换语言,不跟随系统

你可能感兴趣的:(iOS实践——语言切换)