Romowski
Romowski

Reputation: 1548

How can I change application language inside the application?

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.

Upvotes: 2

Views: 2556

Answers (2)

Evol Gate
Evol Gate

Reputation: 2257

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.

Upvotes: 1

Manish Agrawal
Manish Agrawal

Reputation: 11026

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.

Upvotes: 1

Related Questions