2

I would like to change application language inside the app without restarting.

There are Localizable.strings files for both languages. All my XIBs and main Storyboard too.

Te below code can change the language only after restarting an app

main.m:

int main(int argc, char *argv[])
{
    NSString *currLang = [[NSUserDefaults standardUserDefaults] stringForKey:@"Lang"];

    if (!currLang) {
        NSString *languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
        if ([languageCode isEqualToString:@"ru"]) {
            [[NSUserDefaults standardUserDefaults] setValue:languageCode forKey:@"Lang"];
        }
        else [[NSUserDefaults standardUserDefaults] setValue:@"en" forKey:@"Lang"];

        [[NSUserDefaults standardUserDefaults] synchronize];
    }

    currLang = nil;
    currLang = [[NSUserDefaults standardUserDefaults] stringForKey:@"Lang"];
    if ([currLang isEqualToString:@"ru"]) {
        [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"ru", @"en", nil]
                                                  forKey:@"AppleLanguages"];
    }
    else
        [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"en", @"ru", nil]
                                              forKey:@"AppleLanguages"];

    [[NSUserDefaults standardUserDefaults] synchronize];

    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

There are 2 buttons (Eng & Ru) ant the method:

- (IBAction)changeLang:(UIButton *)sender
{
    if ([sender isEqual:btnSetRuLang]) {
        if ([[userDefaults stringForKey:@"Lang"] isEqualToString:@"ru"]) {
            return;
        }
        [userDefaults setValue:@"ru" forKey:@"Lang"];
        [userDefaults synchronize];
    }
    else {
        if ([[userDefaults stringForKey:@"Lang"] isEqualToString:@"en"]) {
            return;
        }
        [userDefaults setValue:@"en" forKey:@"Lang"];
        [userDefaults synchronize];
    }

    NSString *currLang = [userDefaults stringForKey:@"Lang"];
    NSString *alertBody;
    if ([currLang isEqualToString:@"ru"]) {
        [userDefaults setObject:[NSArray arrayWithObjects:@"ru", @"en", nil]
                                                  forKey:@"AppleLanguages"];
        alertBody = @"Перезапустите приложение для смены языка";
    }
    else {
        [userDefaults setObject:[NSArray arrayWithObjects:@"en", @"ru", nil]
                                                  forKey:@"AppleLanguages"];
        alertBody = @"Restart application for change language";
    }

    [userDefaults synchronize];

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Hom" message:alertBody delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alertView show];

}

So, how should I change lang without restarting app?

Thank you.

borrrden
  • 33,256
  • 8
  • 74
  • 109
Romowski
  • 1,518
  • 5
  • 25
  • 50
  • possible duplicate of [Change iOS app's language on the fly](http://stackoverflow.com/questions/6150576/change-ios-apps-language-on-the-fly) – Raptor Aug 07 '13 at 03:46
  • Do you have en.strings & ru.strings in your project? Looking at the code you have posted above, it doesn't seems like you are doing localization the right way. – Evol Gate Aug 07 '13 at 03:50
  • @EvolGate: i have Localizable.strings (English) & Localizable.strings (Russian) – Romowski Aug 07 '13 at 03:55
  • So how are you using these files? Can you post that code. I'd like to check something – Evol Gate Aug 07 '13 at 04:02
  • for example, in my **viewDidLoad** of some controller: `[self.btnCurrent setTitle:NSLocalizedString(@"COOKING", nil) forState:UIControlStateNormal];` – Romowski Aug 07 '13 at 04:33
  • I would strongly discourage to do that. Language should be based on language on the device. There isn't an easy way to do that. Also because most services (such as MAPS) will send request in current device language. To make a localization in the suggested way you will also need to localize all text programmatically. – Andrea Aug 07 '13 at 06:55

2 Answers2

1

I have did the same in one of my application, When user changes the language I did the same and reload all my View controllers which are in navigation stack by calling setNeedsDisplay, that renders the view again with new language settings.

EDIT

for each instance of your view controller call [self setNeedsDisplay] or you can replace the self by the instance of your view controller.

Manish Agrawal
  • 10,958
  • 6
  • 44
  • 76
1

I would suggest you to use

NSLocalizedStringFromTable(key, tbl, comment)

instead of NSLocalizedString(key, comment)

This way all you need to do is maintain a variable of table name. Instead of Localizable.strings, use en.strings and ru.strings files and when the language changes pass the table name as en or ru

Also as @Parser suggests, you must refresh your views.

Evol Gate
  • 2,247
  • 3
  • 19
  • 37