美文网首页
iOS实践——语言切换

iOS实践——语言切换

作者: 邓龙 | 来源:发表于2016-04-20 14:52 被阅读587次

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

    语言切换.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 <Foundation/Foundation.h>
    
    @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 <Foundation/Foundation.h>
    #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 <Foundation/Foundation.h>
    
    typedef NS_ENUM(NSUInteger,DLLanguageType){
        DLLanguageTypeEn = 0,
        DLLanguageTypeCn
    };
    @interface DLLanguageObject : NSObject<NSCoding>
    
    @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实践——语言切换

          本文链接:https://www.haomeiwen.com/subject/enwzlttx.html