app内切替言語

8018 ワード

AppleLanguagesフィールドを設定すると、次のApp起動時にのみ有効になります.App起動後にBundleが生成されました.AppleLanguagesに対応する国際化ファイルが認識され、App実行中にこのフィールドを設定するのは有効ではありません.そのため、このBundleを修正し、NSBundleの拡張を書きます.
.h
#import 

@interface NSBundle (Language)

+ (void)setLanguage:(NSString *)language;

@end

.m
#import "NSBundle+Language.h"
#import 

static const char _bundle = 0;

@interface BundleEx : NSBundle

@end

@implementation BundleEx

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
    NSBundle *bundle = objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}

@end

@implementation NSBundle (Language)

+ (void)setLanguage:(NSString *)language {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        object_setClass([NSBundle mainBundle], [BundleEx class]);
    });

    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

言語ページの切り替え
#import "ViewController3.h"
#import "ZHTabBarController.h"
#import "NSBundle+Language.h"
@interface ViewController3 ()
@property (weak, nonatomic) IBOutlet UIButton *chineseBtn;
@property (weak, nonatomic) IBOutlet UIButton *englishBtn;
@end
@implementation ViewController3
- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.chineseBtn setTitle:NSLocalizedString(@"btn1", nil) forState:UIControlStateNormal];
    [self.englishBtn setTitle:NSLocalizedString(@"btn2", nil) forState:UIControlStateNormal];
}
- (IBAction)chineseBtnAction:(id)sender {
    [self changeLanguageTo:@"zh-Hans"];
}
- (IBAction)englishBtnAction:(id)sender {
    [self changeLanguageTo:@"en"];
}
- (void)changeLanguageTo:(NSString *)language {
//言語設定
    [NSBundle setLanguage:language];
    
//設定した言語を保存し、次に直接ロードします
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:@"myLanguage"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
//システムwindownのrootView Controlを置き換える
    ZHTabBarController *tab = [[ZHTabBarController alloc] init];
    [UIApplication sharedApplication].keyWindow.rootViewController = tab;
//設定ページにジャンプ
    tab.selectedIndex = 2;
}
appDelegateのメソッドは次のように変更されました.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([[NSUserDefaults standardUserDefaults] objectForKey:@"myLanguage"] && ![[[NSUserDefaults standardUserDefaults] objectForKey:@"myLanguage"] isEqualToString:@""]) {
        [NSBundle setLanguage:[[NSUserDefaults standardUserDefaults] objectForKey:@"myLanguage"]];
    }

    //      
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [[ZHTabBarController alloc] init];
    [self.window makeKeyAndVisible];

    return YES;
}