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:@"验证码登录"];
相关推荐
报错小能手17 分钟前
ios开发方向——对于实习开发的app(Robopocket)讲解
开发语言·学习·ios·swift
wechatbot8881 小时前
【企业通信】基于IPAD协议的企业微信群聊管理API:群操作功能接口设计与实现
java·ios·微信·企业微信·ipad
胖虎13 小时前
我用一个 UITableView,干掉了 80% 复杂页面
ios·架构·cocoa·uitableview·ui布局
T1an-13 小时前
最右IOS开发A卷笔试题3.31
c++·ios
wzl202612134 小时前
《从协议层对抗折叠:iPad协议脚本在企微批量群发中的集成与优化》
ios·企业微信·ipad
season_zhu5 小时前
聊聊我最近都干了些什么,AI 时代的手动撸码人
flutter·ios·ai编程
FreeBuf_5 小时前
俄罗斯关联APT组织TA446利用DarkSword漏洞工具包针对iPhone用户发起钓鱼攻击
ios·iphone
Digitally5 小时前
三种将文件从iPhone传输到 Windows 11的方法
ios·iphone
搜佛说5 小时前
14-第14章-扩展点与插件机制
物联网·ios·开源·软件工程·边缘计算·iphone
golang学习记6 小时前
macOS 技巧:使用修饰键控制热角(Hot Corners)
macos