iOS – 通过按钮更改用户的语言

我正在制作一个只使用自定义图形和叙述的互动儿童故事。

我有英语和西class牙语的所有图形。

我没有任何非自定义按钮,没有文本字段,没有任何地方的单一“标准”Apple应用程序UI元素。 一切都是自定义的PNG文件。

我只是在寻找一种方法,允许用户从英语变为西class牙语,反之亦然。

我已经创建了一个自定义英语和西class牙语按钮,按下后会突出显示。

应用程序将(从我读过的内容需要重新启动)然后应用程序将显示其西class牙语页面(以及嵌入在PNG中的西class牙语文本)。 西class牙的叙述将随之而来。

在任何时候,用户都可以选择点击英语语言按钮,并在需要时返回英语。

Tabtale的“美人鱼公主”应用程序做得非常好,远远超过我的需要,但是我所追求的是一个很好的例子。 您单击按钮,更改区域,重新启动应用程序,以及所选区域的所有自定义文本和旁白结果。

我只有两个区域(语言),所以我的需求要简单得多。

但是世界上究竟如何实现这一目标呢?

干杯!

好吧,这比我预期的要困难得多……


基本上我正在交换NSBundle的方法,它将由NSLocalizedString(…)通过使用NSBundle上的类别和一种名为isa-swizzeling的技术来调用


一个NSBundle + Language.h

 #import  @interface NSBundle (Language) +(void)setLanguage:(NSString*)language; @end 

一个NSBundle + Language.m

 #import "NSBundle+Language.h" #import  static const char associatedLanguageBundle=0; @interface PrivateBundle : NSBundle @end @implementation PrivateBundle -(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName { NSBundle* bundle=objc_getAssociatedObject(self, &associatedLanguageBundle); 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],[PrivateBundle class]); }); objc_setAssociatedObject([NSBundle mainBundle], &associatedLanguageBundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end 

AppDelegate将侦听LANGUAGE_WILL_CHANGE通知,设置语言并广播通知LANGUAGE_DID_CHANGE

AppDelegate.m

 #import "AppDelegate.h" #import "NSBundle+Language.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageWillChange:) name:@"LANGUAGE_WILL_CHANGE" object:nil]; NSString *targetLang = [[NSUserDefaults standardUserDefaults] objectForKey:@"selectedLanguage"]; [NSBundle setLanguage:targetLang?:@"en"]; return YES; } -(void)languageWillChange:(NSNotification *) noti { NSString *targetLang = [noti object]; [[NSUserDefaults standardUserDefaults] setObject:targetLang forKey:@"selectedLanguage"]; [NSBundle setLanguage:targetLang]; [[NSNotificationCenter defaultCenter] postNotificationName:@"LANGUAGE_DID_CHANGE" object:targetLang]; } @end 

BaseViewController将发布LANGUAGE_WILL_CHANGE并侦听LANGUAGE_DID_CHANGE


BaseViewController.h

 #import  @interface BaseViewController : UIViewController -(void) languageDidChange; - (IBAction)switchLanguage:(id)sender; @end 

BaseViewController.m

 #import "BaseViewController.h" @interface BaseViewController () @property (weak, nonatomic) IBOutlet UIButton *englishButton; @property (weak, nonatomic) IBOutlet UIButton *spanishButton; @end @implementation BaseViewController - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageDidChangeNotification:) name:@"LANGUAGE_DID_CHANGE" object:nil]; } - (IBAction)switchLanguage:(id)sender { NSString *localString; if (self.englishButton == sender) { localString = @"en"; } else if(self.spanishButton == sender){ localString = @"es"; } if (localString) { [[NSNotificationCenter defaultCenter] postNotificationName:@"LANGUAGE_WILL_CHANGE" object:localString]; } } -(void)languageDidChangeNotification:(NSNotification *)notification { [self languageDidChange]; } -(void)languageDidChange { } @end 

现在任何子类BaseViewController视图控制器都可以实现languageDidChange来调用NSLocalizedString


ViewController.m

 #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *label; @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self languageDidChange]; } -(void)languageDidChange { self.label.text = NSLocalizedString(@"Hello World", nil); self.imageView.image = [UIImage imageNamed:NSLocalizedString(@"image.png", nil)]; } @end 

广告你看,我只是本地化图像名称,我将图像en_image.pnges_image.png添加到图像资产包并将它们映射到可本地化的字符串

 "image.png" = "en_image.png"; 

 "image.png" = "es_image.png"; 

结果

在此处输入图像描述


你会在这里找到这个示例代码: https : //github.com/vikingosegundo/ImmidiateLanguageChange