Reload storyboard to change locale

后端 未结 2 1738
梦毁少年i
梦毁少年i 2020-12-14 12:51

I am using a single, localized Storyboard for my application. The app has to have an option to change language on the fly. So far I figured out how to change the language wh

相关标签:
2条回答
  • 2020-12-14 12:52

    I have the application with on the fly language change and I just pop all the controller and reinitialise the Navigation controller.

    0 讨论(0)
  • 2020-12-14 13:07

    So I found that the problem is with Base translation of my Storyboard, which means I had only one Storyboard file and one .strings file per language for it. It can't be done using Base translations, Apple does not support it.

    So my workaround was the following:

    • Convert Base translations to one Storyboard each language (you can do it in Xcode when you click the Storyboard and set the type to Storyboard from Strings). You can delete the Base at the end.

    • Translate the strings in your Storyboards

    • In the button handler of your language change button do the following:

    (I am using tab controller as root controller, you should change this to your root controller type.)

    [[NSDefaults standardDefaults] setObject:[NSArray arrayWithObject:@"hu"] forKey:@"AppleLanguages"];
    [[NSDefaults standardDefaults] synchronize];
    
    GKAppDelegate *appDelegate = (GKAppDelegate *)[[UIApplication sharedApplication] delegate];        
    UITabBarController* tabBar = (UITabBarController *)appDelegate.window.rootViewController;
    
    // reload the storyboard in the selected language
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:appDelegate.lang ofType:@"lproj"];
    NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
    UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:bundle];
    
    // reload the view controllers
    UINavigationController *placesTab = (UINavigationController *)[storyBoard instantiateViewControllerWithIdentifier:@"placesTab"];
    UINavigationController *informationTab = (UINavigationController *)[storyBoard instantiateViewControllerWithIdentifier:@"informationTab"];
    
    // set them
    NSArray *newViewControllers = @[placesTab, informationTab];
    tabBar.viewControllers = newViewControllers;
    
    • this is not enough. After this, strings form Storyboard should change language, but strings from code don't. For that you have to do this:

    In your appname.pch file:

    #define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]
    

    And you should change all of this:

    NSLocalizedString(@"key", @"comment")
    

    to this:

    NSLocalizedStringFromTableInBundle(@"key", nil, currentLanguageBundle, @"");
    

    Please notice, that I removed the second parameter, the comment. It seems comments with non-ASCII letters can cause trouble, so it's better to avoid them at this point.

    • now every string has to work fine. There is only one thing left: images which you set in your Storyboards disappear when you change language, because iOS does not find them in the bundle. The solution for this is to localize all of them (using the "Localize..." button in the File inspector). This obviously duplicates the images, but don't worry, will not affect your .ipa size, because ZIP handles duplicates very well. (I've got only a 800 → 850k size bump.)

    The adventages of this method:

    • you can use system tools to gather strings to .strings files

    • the UI will not flicker when you change language

    • you don't have to write a lot of code or use a lot of outlets

    • language changig code needs to be ran only once, when the user pushes the button

    I hope this helps, and maybe you can improve my solution.

    0 讨论(0)
提交回复
热议问题