iOS app语言切换

一、准备工作

1、在Project中的info新增需要支持的语言

2、新增.string语言文件用于文本替换,在文件中写入,比如繁体中写入 "用户协议" = "用戶協議";

二、新建语言控制类代码

1、LanguageManager.h

复制代码
#import <Foundation/Foundation.h>

extern NSString * const LanguageDidChangeNotification;

typedef enum : NSUInteger {
    RegionTypeMainlandChina,
    RegionTypeHongKong,
    RegionTypeMacau,
} RegionType;

typedef enum : NSUInteger {
    LanguageTypeSimplifiedChinese,
    LanguageTypeTraditionalChinese,
    LanguageTypeEnglish,
} LanguageType;

@interface LanguageManager : NSObject

+ (instancetype)sharedManager;

/// 设置app语言
/// - Parameter language: 语言代码 如 @"en", @"zh-Hans"
- (void)setLanguage:(NSString *)language;

/// 获取系统语言转换后的字符串数组
/// - Parameter array: 字符串数组
- (NSMutableArray *)localizedArray:(NSArray *)array;

/// 获取系统语言转换后的字符串
/// - Parameter key: 字符串key
- (NSString *)localizedStringForKey:(NSString *)key;

/// 获取当前语言
- (NSString *)currentLanguage;

/// 获取用户系统设置地区
@property (nonatomic, assign) RegionType regionType;

/// 获取用户系统设置语言,只做获取不做设置
@property (nonatomic, assign) LanguageType languageType;

@end

2、LanguageManager.m

复制代码
#import "LanguageManager.h"

#define kAppLanguage @"AppLanguage"

NSString * const LanguageDidChangeNotification = @"LanguageDidChangeNotification";

@interface LanguageManager ()
@property (nonatomic, strong) NSBundle *bundle;
@end

@implementation LanguageManager

+ (instancetype)sharedManager {
    static LanguageManager *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[LanguageManager alloc] init];
    });
    return instance;
}

- (instancetype)init {
    if (self = [super init]) {
        NSString *language = [[NSUserDefaults standardUserDefaults] objectForKey:kAppLanguage];
        if (!language) language = [NSLocale preferredLanguages].firstObject;
        [self updateBundleWithLanguage:language];
    }
    return self;
}

- (void)setLanguage:(NSString *)language {
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:kAppLanguage];
    [[NSUserDefaults standardUserDefaults] synchronize];
    [self updateBundleWithLanguage:language];
    
    // 保存语言到用户偏好设置
    kUser.languageCode = language;
    
    // 发送语言改变通知
    [[NSNotificationCenter defaultCenter] postNotificationName:LanguageDidChangeNotification object:nil];
}

- (NSMutableArray *)localizedArray:(NSArray *)array {
    NSMutableArray *localized = [NSMutableArray array];
    for (NSString *key in array) {
        NSString *text = [self localizedStringForKey:key];
        [localized addObject:text];
    }
    return localized;
}

- (void)updateBundleWithLanguage:(NSString *)language {
    NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"];
    if (path) {
        self.bundle = [NSBundle bundleWithPath:path];
    } else {
        self.bundle = [NSBundle mainBundle];
    }
}

- (NSString *)localizedStringForKey:(NSString *)key {
    return [self.bundle localizedStringForKey:key value:nil table:@"Localizable"];
}

- (NSString *)currentLanguage {
    return [[NSUserDefaults standardUserDefaults] objectForKey:kAppLanguage];
}

- (RegionType)regionType {
    NSString *countryCode = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
    if ([countryCode isEqualToString:@"CN"]) {
        return RegionTypeMainlandChina;
    } else if ([countryCode isEqualToString:@"HK"]) {
        return RegionTypeHongKong;
    } else if ([countryCode isEqualToString:@"MO"]) {
        return RegionTypeMacau;
    } else {
        return RegionTypeMainlandChina;
    }
}

- (LanguageType)languageType {
    NSString *languageCode = [self currentLanguage];
    if ([languageCode isEqualToString:@"zh-Hans"]) {
        return LanguageTypeSimplifiedChinese;
    } else if ([languageCode isEqualToString:@"zh-Hant"]) {
        return LanguageTypeTraditionalChinese;
    } else if ([languageCode isEqualToString:@"en"]) {
        return LanguageTypeEnglish;
    } else {
        return LanguageTypeSimplifiedChinese;
    }
}

@end

3、ViewController中切换

可以重新加载VC,也可以自定义一个方法切换,下面仅展示重新加载

在VC中写通知接收,tabbar文本也需要更新,根据需求来

复制代码
[[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(rebuildSelfForLanguageChange)
                                                     name:LanguageDidChangeNotification
                                                   object:nil];

- (void)rebuildSelfForLanguageChange {
    UINavigationController *nav = self.navigationController;
    Class cls = [self class];
    UIViewController *newVC = [[cls alloc] init];

    // 保留 TabBarItem
    newVC.tabBarItem = self.tabBarItem;

    NSMutableArray *controllers = [nav.viewControllers mutableCopy];
    NSUInteger idx = [controllers indexOfObject:self];
    controllers[idx] = newVC;
    [nav setViewControllers:controllers animated:NO];
}

如果是在没有tabbar的子页面可以这样初始化,避免重新加载后后tabbar突然出现

复制代码
- (void)rebuildSelfForLanguageChange {
    UINavigationController *nav = self.navigationController;
    Class cls = [self class];
    UIViewController *newVC = [[cls alloc] init];

    // 保留 hidesBottomBarWhenPushed
    newVC.hidesBottomBarWhenPushed = self.hidesBottomBarWhenPushed;

    NSMutableArray *controllers = [nav.viewControllers mutableCopy];
    NSUInteger idx = [controllers indexOfObject:self];
    controllers[idx] = newVC;
    [nav setViewControllers:controllers animated:NO];
}

4、调用示例

复制代码
//可以在AppDelegate中设置初始化语言
- (void)initWindow {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = kWhiteColor;
    [self.window makeKeyAndVisible];
    kApplication.statusBarHidden = NO;
    
    if (kUser.languageCode.length == 0) {
        NSString *systemLanguage = [NSLocale preferredLanguages].firstObject; // e.g., "zh-Hant-CN"
        NSString *appLanguage = @"en"; // 默认英文

        if ([systemLanguage hasPrefix:@"zh"]) {
            if ([systemLanguage containsString:@"Hant"]) {
                appLanguage = @"zh-Hant"; // 繁体
            } else {
                appLanguage = @"zh-Hans"; // 简体
            }
        } else if ([systemLanguage hasPrefix:@"en"]) {
            appLanguage = @"en"; // 英文
        }

        // 设置语言
        [[LanguageManager sharedManager] setLanguage:appLanguage];
    }
}


//设置好语言之后可以通过这种方式自动匹配繁体或者简体或者英文
_tipText.text = [[LanguageManager sharedManager] localizedStringForKey:@"验证码登录"];
相关推荐
晴天无痕4 小时前
iOS修改tabbar的背景图
macos·ios·cocoa
Digitally4 小时前
5 种无需 iTunes 将 iPad 照片传输到电脑的方法
ios·电脑·ipad
RollingPin4 小时前
iOS八股文之 组件化
ios·路由·router·组件化·imp·分层设计
大熊猫侯佩5 小时前
Thread.sleep 与 Task.sleep 终极对决:Swift 并发世界的 “魔法休眠术” 揭秘
ios·swift·apple
大熊猫侯佩5 小时前
【大话码游之 Observation 传说】下集:破咒终局了,天眼定乾坤
ios·swift·apple
大熊猫侯佩5 小时前
【大话码游之 Observation 传说】中集:仙流暗涌,计数迷踪现
ios·swift·apple
大熊猫侯佩5 小时前
寥寥几行代码实现 SwiftUI 超丝滑弹窗转场动画
ios·swiftui·swift