I'm trying to add an option for the user to switch between Arabic & English language from inside the app (without having to re-set the language of the whole iPhone), I managed to do it correctly by using this method in the AppDelegate.m file:
我正在尝试为用户添加一个选项,以便在应用程序内部切换阿拉伯语和英语(无需重新设置整个iPhone的语言),我设法在AppDelegate中使用此方法正确完成.m文件:
-(void)switchTolanguage:(NSString *)lang{
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:lang] forKey:@"AppleLanguages"];
NSBundle *bnd = [NSBundle bundleWithPath:[[NSBundle mainBundle]pathForResource:lang ofType:@"lproj" ]];
UIStoryboard *storyBoard;
storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:bnd];
UIViewController *initViewController = [storyBoard instantiateInitialViewController];
self.window.rootViewController = initViewController;
}
I placed two UIButtons
on one of the view controllers in the app to test the method and it worked well: all UILabels
, strings, etc ... in the new loaded (localized) storyboard appear with the correct selected language but with one exception: the new loaded storyboard does not take (load) its localized images, it takes the images for the old storyboard (old bundle), i.e. if the app currently runs on English bundle and the user tapped on the button that switches the language to Arabic, the app will appear with the correct Arabic controls and strings but with English images, switch back to english everything will be OK (english strings, labels and images ...)
我在应用程序中的一个视图控制器上放置了两个UIButton来测试方法,并且它运行良好:新加载(本地化)故事板中的所有UILabel,字符串等都显示正确的选定语言,但有一个例外:新加载的故事板不会(加载)其本地化图像,它会拍摄旧故事板(旧软件包)的图像,即如果应用程序当前在英文软件包上运行,并且用户点击了将语言切换为阿拉伯语的按钮,该应用程序将显示正确的阿拉伯语控件和字符串,但有英文图像,切换回英语一切都会好(英文字符串,标签和图像......)
here's how my storyboard is localized:
这是我的故事板本地化的方式:
and here's how each image is localized:
以下是每个图像的本地化方式:
How can I load the correct bundle images when the user switches app language ?
当用户切换应用程序语言时,如何加载正确的包图像?
UPDATE:
Here's a link to a sample project for what I mean, run the sample and you will notice when you change the language from inside the app, you will notice that the image is not changeable ... and you will also notice that the localized storyboard does not load the right image in its design editor ...
更新:这是一个示例项目的链接,我的意思是,运行示例,您会注意到当您从应用程序内部更改语言时,您会注意到图像不可更改...而且您还会注意到本地化的故事板不会在其设计编辑器中加载正确的图像...
P.S. do not add comments for why I use such scenario to switch language, because it is a customer requirement.
附:不要为我使用此类场景切换语言的原因添加注释,因为这是客户要求。
3 个解决方案
#1
2
I had same issue :(.. and what worked for me (for such scenarios to switch language) ..
我有同样的问题:( ..和什么对我有用(对于这种场景切换语言)..
You have 2 possibilities..
你有两种可能性..
1) If you want to change the storyboard (hot change), you must modify all your Outlets in the each Storyboard. Choose in your storyboard the desired image (with different names), labels, etc.. For me, with localized images (same name) - only worked after restart of the application.. For the same img_name, I' tried ... to "call" the specific image.. from the specific lproj folder (languageBundle).. but it did not work at changed the storyboard from AppDelegate..
1)如果要更改故事板(热更改),则必须修改每个故事板中的所有插座。在故事板中选择所需的图像(具有不同的名称),标签等。对于我来说,使用本地化的图像(相同的名称) - 仅在重新启动应用程序后才能工作..对于相同的img_name,我试过......从特定的lproj文件夹(languageBundle)“调用”特定的图像..但它在AppDelegate改变故事板时无效。
2) You can have only one storyboard... and change only labels, image, etc... (according to Localizable.strings), something linke this... https://*.com/a/12149553/1702413 Also, you must have different file name for images (for "hot changing")
2)你可以只有一个故事板...并且只更改标签,图像等...(根据Localizable.strings),这个东西可以解决这个问题... https://*.com/a/12149553/1702413 ,你必须有不同的图像文件名(用于“热变”)
I don't know if a bug... or what is...
我不知道是不是一个bug ......或者是什么......
UPD
You have a little project https://dl.dropbox.com/u/19438780/test5%20copy2.zip with both..
你有一个小项目https://dl.dropbox.com/u/19438780/test5%20copy2.zip与两个..
If you are changing the storyboard (like you) you will have the same path for languageBundle until you restart the application. So.. you must do the changing right in your storyboard..
如果您要更改故事板(与您一样),则在重新启动应用程序之前,您将拥有languageBundle的相同路径。所以..你必须在你的故事板中做正确的改变..
For the second.. you can change/recall outlets .. from specific languageBundle (lproj folders)..
对于第二个..你可以从特定的languageBundle(lproj文件夹)更改/召回插座..
For 1) .. I found a "trick" to overwrite the languageBundle until restart:
对于1)..我发现了一个“技巧”来覆盖languageBundle直到重启:
-(id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
Lang2 = [languages objectAtIndex:0]; //NSString
}
return self;
}
and init the Outlets:
并初始化奥特莱斯:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
NSString *path;
if([Lang2 isEqualToString: @"ro"])
{
path = [[NSBundle mainBundle] pathForResource:@"ro" ofType:@"lproj"];
NSLog(@"enc ro");
}
else{
path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
NSLog(@"enc en");
}
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
//find and return the desired string
self.label.text=[languageBundle localizedStringForKey:@"kLabelText" value:@"" table:nil];
self.img.image = [UIImage imageNamed:[languageBundle localizedStringForKey:@"myImage" value:@"" table:nil]];
}
#2
1
You have to reload all the views that contains multilingual text which can't be done as if the view has referenced objects in the controller then the result is unknown and most probably it will crash.
您必须重新加载包含多语言文本的所有视图,这些视图无法完成,就好像视图已在控制器中引用了对象,然后结果未知且很可能会崩溃。
A correct and efficient approach will be to have a dictionary for each language that you can switch based on language selected. Draw all the static text this way you can easily draw it back when the language changes. On language change post a notification to controllers to redraw the view. For images you can do similar draw them or have reference to them that you can change.
一种正确而有效的方法是为每种语言提供一个字典,您可以根据所选语言进行切换。以这种方式绘制所有静态文本,您可以在语言更改时轻松地将其绘制回来。在语言更改时向控制器发送通知以重绘视图。对于你可以做类似的图像绘制它们或参考它们你可以改变。
One there thing you can do for images is to have a custom image view class that also observe the language change notification and automatically loads the appropriate image. Same you can do for labels.
您可以为图像做的一件事就是拥有一个自定义图像视图类,它还可以观察语言更改通知并自动加载适当的图像。您可以为标签做同样的事情。
I can code something for you if you need an example.
如果你需要一个例子,我可以为你编写代码。
#3
-1
NSBundle *bundle = [LocalizationSystem sharedBundle]; //this get your current bundle
NSString *imgPath = [bundle pathForResource:@"btn-Image" ofType:@"png" inDirectory:nil];
[self.btnTest setImage:[UIImage imageWithContentsOfFile:imgPath] forState:UIControlStateNormal];
#1
2
I had same issue :(.. and what worked for me (for such scenarios to switch language) ..
我有同样的问题:( ..和什么对我有用(对于这种场景切换语言)..
You have 2 possibilities..
你有两种可能性..
1) If you want to change the storyboard (hot change), you must modify all your Outlets in the each Storyboard. Choose in your storyboard the desired image (with different names), labels, etc.. For me, with localized images (same name) - only worked after restart of the application.. For the same img_name, I' tried ... to "call" the specific image.. from the specific lproj folder (languageBundle).. but it did not work at changed the storyboard from AppDelegate..
1)如果要更改故事板(热更改),则必须修改每个故事板中的所有插座。在故事板中选择所需的图像(具有不同的名称),标签等。对于我来说,使用本地化的图像(相同的名称) - 仅在重新启动应用程序后才能工作..对于相同的img_name,我试过......从特定的lproj文件夹(languageBundle)“调用”特定的图像..但它在AppDelegate改变故事板时无效。
2) You can have only one storyboard... and change only labels, image, etc... (according to Localizable.strings), something linke this... https://*.com/a/12149553/1702413 Also, you must have different file name for images (for "hot changing")
2)你可以只有一个故事板...并且只更改标签,图像等...(根据Localizable.strings),这个东西可以解决这个问题... https://*.com/a/12149553/1702413 ,你必须有不同的图像文件名(用于“热变”)
I don't know if a bug... or what is...
我不知道是不是一个bug ......或者是什么......
UPD
You have a little project https://dl.dropbox.com/u/19438780/test5%20copy2.zip with both..
你有一个小项目https://dl.dropbox.com/u/19438780/test5%20copy2.zip与两个..
If you are changing the storyboard (like you) you will have the same path for languageBundle until you restart the application. So.. you must do the changing right in your storyboard..
如果您要更改故事板(与您一样),则在重新启动应用程序之前,您将拥有languageBundle的相同路径。所以..你必须在你的故事板中做正确的改变..
For the second.. you can change/recall outlets .. from specific languageBundle (lproj folders)..
对于第二个..你可以从特定的languageBundle(lproj文件夹)更改/召回插座..
For 1) .. I found a "trick" to overwrite the languageBundle until restart:
对于1)..我发现了一个“技巧”来覆盖languageBundle直到重启:
-(id) initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
Lang2 = [languages objectAtIndex:0]; //NSString
}
return self;
}
and init the Outlets:
并初始化奥特莱斯:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
NSString *path;
if([Lang2 isEqualToString: @"ro"])
{
path = [[NSBundle mainBundle] pathForResource:@"ro" ofType:@"lproj"];
NSLog(@"enc ro");
}
else{
path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
NSLog(@"enc en");
}
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
//find and return the desired string
self.label.text=[languageBundle localizedStringForKey:@"kLabelText" value:@"" table:nil];
self.img.image = [UIImage imageNamed:[languageBundle localizedStringForKey:@"myImage" value:@"" table:nil]];
}
#2
1
You have to reload all the views that contains multilingual text which can't be done as if the view has referenced objects in the controller then the result is unknown and most probably it will crash.
您必须重新加载包含多语言文本的所有视图,这些视图无法完成,就好像视图已在控制器中引用了对象,然后结果未知且很可能会崩溃。
A correct and efficient approach will be to have a dictionary for each language that you can switch based on language selected. Draw all the static text this way you can easily draw it back when the language changes. On language change post a notification to controllers to redraw the view. For images you can do similar draw them or have reference to them that you can change.
一种正确而有效的方法是为每种语言提供一个字典,您可以根据所选语言进行切换。以这种方式绘制所有静态文本,您可以在语言更改时轻松地将其绘制回来。在语言更改时向控制器发送通知以重绘视图。对于你可以做类似的图像绘制它们或参考它们你可以改变。
One there thing you can do for images is to have a custom image view class that also observe the language change notification and automatically loads the appropriate image. Same you can do for labels.
您可以为图像做的一件事就是拥有一个自定义图像视图类,它还可以观察语言更改通知并自动加载适当的图像。您可以为标签做同样的事情。
I can code something for you if you need an example.
如果你需要一个例子,我可以为你编写代码。
#3
-1
NSBundle *bundle = [LocalizationSystem sharedBundle]; //this get your current bundle
NSString *imgPath = [bundle pathForResource:@"btn-Image" ofType:@"png" inDirectory:nil];
[self.btnTest setImage:[UIImage imageWithContentsOfFile:imgPath] forState:UIControlStateNormal];