Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

loading images from the correct bundle when localizing storyboards

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:

 -(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 ...)

here's how my storyboard is localized:

enter image description here

and here's how each image is localized:

enter image description here

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.

like image 887
JAHelia Avatar asked Feb 06 '13 13:02

JAHelia


2 Answers

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..

2) You can have only one storyboard... and change only labels, image, etc... (according to Localizable.strings), something linke this... https://stackoverflow.com/a/12149553/1702413 Also, you must have different file name for images (for "hot changing")

I don't know if a bug... or what is...

UPD

You have a little project https://dl.dropbox.com/u/19438780/test5%20copy2.zip with both..

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..

For the second.. you can change/recall outlets .. from specific languageBundle (lproj folders)..

For 1) .. I found a "trick" to overwrite the languageBundle until restart:

-(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]];
}
like image 132
TonyMkenu Avatar answered Oct 23 '22 06:10

TonyMkenu


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.

like image 1
SAPLogix Avatar answered Oct 23 '22 06:10

SAPLogix