天天看點

[IOS]如何在app裡面改變語言

參考:​​https://stackoverflow.com/questions/9416923/ios-how-to-change-app-language-programmatically-without-restarting-the-app​​

核心是使用

NSString *path = [[NSBundle mainBundle]pathForResource:currentLanguage ofType:@"lproj"];
    
    if (path) {
        localeBundle = [NSBundle bundleWithPath:path];
        
    }else{
         localeBundle= [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj" ]];
    }      

 改變localeBundle的值

思路:

1.使用

NSLocalizedStringFromTableInBundle(@"TNC_title", nil, localeBundle] , @""),      

 可以實時變換不同的國際化檔案

*國際化檔案一般在檔案目錄系統是放在lproj字尾的檔案夾中的:形式如zh-Hant.lproj(繁體)zh-Hants.lproj(簡體)en.lproj(英文)

是以在上文的pathForResource:currentLanguage中也需要對應相應的檔案名。

2.再重新整理一遍UI的text擷取

基于項目的代碼示例:

建一個工具類.h:

#import <Foundation/Foundation.h>

@interface LanguageTool : NSObject



+(instancetype)getInstance;

- (NSBundle *)getLocaleBundle;

-(NSString *)getTap;

-(NSString *)getCurrentLanguage;

-(void)changeLanguage:(NSString*)language;


@end      

.m:

#import "LanguageTool.h"
#import "SessionManager.h"

#define CNS @"zh"
#define EN @"en"
#define tap @"change_language"

static NSBundle *localeBundle = nil;
static NSString *currentLanguage = nil;

@interface LanguageTool()


@end

@implementation LanguageTool

//單例
+(instancetype)getInstance{
    static LanguageTool *manager = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
        manager = [[LanguageTool alloc] init];
    });
    return manager;
}


-(void)changeLanguage:(NSString*)language{
    
    currentLanguage = language;
    
    NSString *path = [[NSBundle mainBundle]pathForResource:language ofType:@"lproj"];
    
    if (path && ![@"en" isEqualToString:language]) {
        localeBundle = [NSBundle bundleWithPath:path];
    }else{
        localeBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj" ]];
    }
}

//這個方法的目的是,如果什麼都沒有選擇,就使用系統預設語言,否則使用使用者選擇的語言,并且不會因為關閉app而改變。
-(void)judgeLanguage{
    
    //Get last change language
    NSString *lastChangeLanguage = nil;
//使用一個持久化,保持上次的語言選擇
    lastChangeLanguage = [SessionManager getSession:[SessionManager getLastLanguageTap]];
    NSLog(@"last chage language: %@",lastChangeLanguage);
    
    //語言優先級:currentLanguage > lastChangeLanguage > system default language
    //user 沒有設定語言時:擷取系統預設語言
    if (!lastChangeLanguage) {
        if (!currentLanguage) {
            //擷取系統預設語言:
            //截取:zh-Hant-HK 去掉區域保留:zh-Hant
            NSLog(@"-------system language:%@",[NSLocale preferredLanguages][0]);
            currentLanguage = [[NSLocale preferredLanguages][0] substringToIndex:2];
            if ([currentLanguage containsString:@"zh"]) {
                
                currentLanguage = [NSString stringWithFormat:@"%@%@",currentLanguage,@"-Hant"];
            }
        }
    }else if(!currentLanguage){
        //目前沒有切換語言,app内有設定語言,優先app内語言
        currentLanguage = lastChangeLanguage;
    }

}

- (NSBundle *)getLocaleBundle{
    
    [self judgeLanguage];
    
    NSLog(@"------current language :%@",currentLanguage);
    NSLog(@"-------system language:%@",[NSLocale preferredLanguages][0]);

    NSString *path = [[NSBundle mainBundle]pathForResource:currentLanguage ofType:@"lproj"];
    
    if (path) {
        localeBundle = [NSBundle bundleWithPath:path];
        
    }else{
         localeBundle= [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj" ]];
    }
    return localeBundle;
}

//标記
-(NSString *)getTap{
    return tap;
}

-(NSString *)getCurrentLanguage{
//    if (!currentLanguage) {
//        //截取:zh-Hant-HK 去掉區域保留:zh-Hant
//        currentLanguage = [[NSLocale preferredLanguages][0] substringToIndex:2];
//    }
    
    [self judgeLanguage];
    
    NSLog(@"current language:%@",currentLanguage);
    return currentLanguage;
}

@end      

使用在需要切換語言的地方點選後調用:

//如果目前是英語就切換成繁體
if ([@"en" isEqualToString:[[LanguageTool getInstance] getCurrentLanguage]]) {
                [self changeLanguage:@"zh-Hant"];
            } else {
                [self changeLanguage:@"en"];
            }
//通知其他頁面也切換語言
            [self callLanguageChangeNotificationReceiver];      
-(void)changeLanguage:(NSString*)language{
    
    [[LanguageTool getInstance] changeLanguage:language];
    
//重新整理某些UI text
    [self initTableResource];
    
    [_tableView reloadData];
    
    
}      

 //例如這樣重新整理:

-(void)initTableResource{
    
    _dataArray = @[NSLocalizedStringFromTableInBundle(@"Home", nil, [[LanguageTool getInstance] getLocaleBundle] , @""),
                   NSLocalizedStringFromTableInBundle(@"customization", nil, [[LanguageTool getInstance] getLocaleBundle] , @"")
                   ,
                   NSLocalizedStringFromTableInBundle(@"TNC_title", nil, [[LanguageTool getInstance] getLocaleBundle] , @""),
                   NSLocalizedStringFromTableInBundle(@"localizable", nil, [[LanguageTool getInstance] getLocaleBundle] , @"")];
    
    NSString *app_version = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    _app_version_string = [NSString stringWithFormat:@"%@ %@",NSLocalizedStringFromTableInBundle(@"slider_version_info", nil, [[LanguageTool getInstance] getLocaleBundle] , @""),app_version];
    if (_version_label) {
        _version_label.text = _app_version_string;
    }
   
    
    [self initContentVersionLabel];
    
}      

//設定通知:

-(void)callLanguageChangeNotificationReceiver{
    
    [SessionManager setSession:[SessionManager getLastLanguageTap]
                         value:[[LanguageTool getInstance] getCurrentLanguage]];
    
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    
    [center postNotificationName:[[LanguageTool getInstance] getTap] object:nil];
    
}      

被通知的頁面接收通知,并重新整理一下UI,操作并不複雜:

-(void)initNotification{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshTextView) name:[[LanguageTool getInstance]getTap] object:nil];
}

-(void)refreshTextView{
    _tncTextView.text = NSLocalizedStringFromTableInBundle(@"TNC_text", nil, [[LanguageTool getInstance] getLocaleBundle] , @"");
    _navItem.title = NSLocalizedStringFromTableInBundle(@"TNC_title", nil, [[LanguageTool getInstance] getLocaleBundle] , @"");
}