2

I'm developing an iOS app with two languages. I localized the main storyboard for each language and now I'm trying to switch between languages using the same button (toggled button text).

I found many codes for changing the app language with buttons for each one like this and Advance-Localization-in-ios-apps but I don't know how to reload the storyboard with its .strings depending on the selected language in the button. Any help please? thanks

localized Main.storyboard English strings file

Community
  • 1
  • 1
Mane_87
  • 35
  • 3
  • 9
  • Can you share a screenshot of how your localized strings files and storyboards are organized? I need it to tell more relevant answer – Ducky Sep 16 '15 at 11:28
  • Thanks for the comment, I added the screenshots of storyboard and strings file. – Mane_87 Sep 16 '15 at 12:07
  • @Mane_87 . i am new to localisation . i am working 3 different languages how can in change the language – Uma Madhavi Sep 15 '17 at 09:59

1 Answers1

4

I am afraid that you can't use Main.strings files. You will end up moving all localisable texts in the storyboard to Localizable.strings and load the them from there using a method like NSLocalizedString(key, comment).

Here is a Working sample project on GitHub. It works as in the screenshot below:

enter image description here

Complete code for the demo view controller

#import "ViewController.h"

//--------------- Modify NSBunle behavior -------------
#import <objc/runtime.h>

@interface CustomizedBundle : NSBundle
@end

@implementation CustomizedBundle
static const char kAssociatedLanguageBundle = 0;

-(NSString*)localizedStringForKey:(NSString *)key
                            value:(NSString *)value
                            table:(NSString *)tableName {

    NSBundle* bundle=objc_getAssociatedObject(self, &kAssociatedLanguageBundle);

    return bundle ? [bundle localizedStringForKey:key value:value table:tableName] :
    [super localizedStringForKey:key value:value table:tableName];
}
@end

@implementation NSBundle (Custom)
+ (void)setLanguage:(NSString*)language {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        object_setClass([NSBundle mainBundle], [CustomizedBundle class]);
    });

    objc_setAssociatedObject([NSBundle mainBundle], &kAssociatedLanguageBundle, language ?
                             [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

//--------------- Demo ---------------------------------
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *button;

@property (nonatomic, assign) BOOL usingArabic;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self localizeTexts];
}

- (void)localizeTexts {
    self.label.text = NSLocalizedString(@"explanation_message", nil);
    [self.button setTitle:NSLocalizedString(@"language_switch_title", nil) forState:UIControlStateNormal];
}


- (IBAction)switchLanguageTouched:(id)sender {
    _usingArabic = !_usingArabic;
    NSString *targetLang = _usingArabic ? @"ar" : @"en";

    [NSBundle setLanguage:targetLang];

    [[NSUserDefaults standardUserDefaults] setObject:targetLang forKey:@"selectedLanguage"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    [NSBundle setLanguage:targetLang];

    [self localizeTexts];
}

@end

Your Localizable files will look like this:

enter image description here

Hope this helps. Happy coding!

Edit: Without calling a method like 'localizeTexts' in the example above to 'refresh' the text value being displayed, it's impossible to reflect the currently selected language. The object is in memory so you must recreate or update its value.

Ducky
  • 2,754
  • 16
  • 25
  • Thank you for the answer. It's OK for the Main.strings files but I'm asking if it's possible to change the language of the whole view and the rest of the application instead of setting all the components like the label and the button in localizeTexts method in your example? Thank you – Mane_87 Sep 17 '15 at 10:06
  • Let's simplify your problem like this: how to reload 1 button text after switching language? The answer is: Without calling a method to 'refresh' the text value being displayed, it's impossible to reflect the currently selected language. The object is in memory so you must recreate or update its value. – Ducky Sep 18 '15 at 17:52
  • Sorry but my problem isn't in the button but I should set all the application on the selected language. It means reloading the storyboard with the appropriate strings file. I tried many ways but I still stuck (like adding ` [(AppDelegate *)[[UIApplication sharedApplication] delegate] window].rootViewController = [self.storyboard instantiateInitialViewController];` and this code [link] http://stackoverflow.com/questions/26496404/how-to-get-localised-storyboard-strings-after-switching-to-language-at-runtime-i ) – Mane_87 Sep 18 '15 at 21:27