You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中使用Objective-C实现应用语言运行时切换无需重启

实现iOS应用实时语言切换(无需重启)

我完全懂你的困扰——直接修改AppleLanguages的方式确实只能在重启后生效,用户体验太差了。要实现下拉选择后立刻切换语言,咱们得自己接管本地化资源的加载逻辑,而不是完全依赖系统的默认机制。下面是一套完整的实现方案:

1. 创建语言管理单例类

首先写一个LanguageManager单例,用来统一管理当前语言、保存用户选择,以及提供自定义的本地化字符串获取方法。

头文件(LanguageManager.h)

#import <Foundation/Foundation.h>

@interface LanguageManager : NSObject

@property (nonatomic, strong) NSString *currentLanguage; // 当前选中的语言代码,比如@"fr"代表法语

+ (instancetype)sharedManager;
- (NSString *)localizedStringForKey:(NSString *)key;

@end

实现文件(LanguageManager.m)

#import "LanguageManager.h"

static NSString *const kCurrentLanguageKey = @"kCurrentLanguageKey";

@implementation LanguageManager

+ (instancetype)sharedManager {
    static LanguageManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[LanguageManager alloc] init];
        // 初始化时读取用户保存的语言,没有则用系统默认语言
        NSString *savedLang = [[NSUserDefaults standardUserDefaults] objectForKey:kCurrentLanguageKey];
        if (!savedLang) {
            savedLang = [[NSLocale preferredLanguages] firstObject];
            // 如果系统语言是中文简体,可能返回@"zh-Hans",可根据需求转换成统一格式
        }
        manager.currentLanguage = savedLang;
    });
    return manager;
}

- (void)setCurrentLanguage:(NSString *)currentLanguage {
    _currentLanguage = currentLanguage;
    // 保存到UserDefaults
    [[NSUserDefaults standardUserDefaults] setObject:currentLanguage forKey:kCurrentLanguageKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    // 发送通知,告诉所有界面需要刷新语言
    [[NSNotificationCenter defaultCenter] postNotificationName:@"LanguageDidChangeNotification" object:nil];
}

- (NSString *)localizedStringForKey:(NSString *)key {
    // 根据当前语言加载对应的strings文件
    NSString *path = [[NSBundle mainBundle] pathForResource:self.currentLanguage ofType:@"lproj"];
    NSBundle *languageBundle = [NSBundle bundleWithPath:path];
    return [languageBundle localizedStringForKey:key value:@"" table:nil];
}

@end

2. 替换所有NSLocalizedString调用

把项目里所有用NSLocalizedString的地方,换成自定义的本地化方法。比如:

// 原来的写法
self.title = NSLocalizedString(@"Home", nil);
// 改成
self.title = [[LanguageManager sharedManager] localizedStringForKey:@"Home"];

3. 实现下拉选择的语言切换逻辑

假设你用UIPickerView做下拉选择,在用户选中新语言时,更新LanguageManager的当前语言:

// UIPickerView的选中回调
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    NSArray *languageNames = @[@"English", @"French", @"Chinese"];
    NSArray *languageCodes = @[@"en", @"fr", @"zh-Hans"];
    NSString *selectedLangCode = languageCodes[row];
    
    [[LanguageManager sharedManager] setCurrentLanguage:selectedLangCode];
}

4. 自动刷新所有界面元素

写一个基类BaseViewController,让所有页面继承它,统一处理语言切换后的UI刷新:

#import <UIKit/UIKit.h>

@interface BaseViewController : UIViewController

@end

@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 监听语言切换通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshLanguage) name:@"LanguageDidChangeNotification" object:nil];
}

- (void)refreshLanguage {
    // 在这里更新当前页面的所有控件文本
    self.title = [[LanguageManager sharedManager] localizedStringForKey:@"Home"];
    self.confirmBtn.titleLabel.text = [[LanguageManager sharedManager] localizedStringForKey:@"Confirm"];
    // 其他控件同理...
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end

额外注意点

  • 确保本地化文件命名正确:比如法语对应fr.lproj/Localizable.strings,中文简体对应zh-Hans.lproj/Localizable.strings
  • 对于XIB/Storyboard里的控件,需要在refreshLanguage里手动更新文本,或者给控件加IBInspectable属性绑定本地化key,实现自动更新
  • 全局UI元素(比如导航栏、标签栏)也要在收到通知时刷新,可在AppDelegate里监听通知统一处理

这样操作后,用户选择语言后就能立刻看到界面切换到对应语言,完全不需要重启应用啦!

内容的提问来源于stack exchange,提问作者Niesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:35:33