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:@"验证码登录"];
相关推荐
ACP广源盛139246256732 小时前
M6/M5 Pro Mac mini 端侧 AI 落地@ACP#YLB3116 中端多盘存储扩展在 AI 服务中的机会与应用场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos
ACP广源盛139246256733 小时前
M6/M5 Pro Mac mini 端侧 AI 新形态@ACP#GSV5800 Serdes 长距离视频传输在 AI 服务中的机会与落地场景
大数据·网络·数据库·人工智能·嵌入式硬件·macos·音视频
代码的小搬运工5 小时前
KVO学习
学习·ios·cocoa
方白羽5 小时前
为什么 Android 非要用 Intent 传值?
android·ios·harmonyos
dora7 小时前
iOS开发新手的第一行代码
ios
mashang12345678913 小时前
mac安装SnailGitLite并配置Beyond Compare
前端·macos
用户380341658829713 小时前
视频编辑器的滤镜图内核:Node/Pin 模型怎么设计,撤销重做怎么才不崩
ios
CocoaKier1 天前
苹果续费成功,几天后付费协议突然失效,导致线上苹果支付全部失败
ios·apple
深念Y1 天前
PVE 安装黑苹果并直通 Quadro P400
macos·ios·黑苹果·驱动·苹果·英伟达·p400
weixin-a153003083161 天前
7.Appium-ios端自动化
ios·appium·自动化