How to force an app to change language in iOS/Objective-C?

I'm having a problem with make app change language immediately like this app.

I've found a lot of similar question like this and this.

But, unfortunately, the related answers to these question don't work for me. I need my app change language immediately when I tap on an cell.

Any ideas? Thank in advance.


Solution 1:

My solution

First you need to create the String File

Go to Project Right Click.
New File->iOS
Under iOS you can see the Resource
Click Resource and you can see the String File among the group of files.
Click that give name whatever you want.

Now you can create the string file below.

"Date"="Date";

"Time"="Time";

"Done"="Done";

 "Back"="Back";

In appDelegate.h

-(NSString*) languageSelectedStringForKey:(NSString*) key
{
  NSString *path;
  AppDelegate *app=(AppDelegate *)[[UIApplication sharedApplication]delegate];
  if(app.currentLanguage==ENGLISH)
  path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
  else if(app.currentLanguage==TAMIL)
  path = [[NSBundle mainBundle] pathForResource:@"ta-IN" ofType:@"lproj"];
  else if(app.currentLanguage==SPANISH)
  path = [[NSBundle mainBundle] pathForResource:@"es" ofType:@"lproj"];
  else if(app.currentLanguage==FRENCH)
  path = [[NSBundle mainBundle] pathForResource:@"fr" ofType:@"lproj"];
  else if(app.currentLanguage==JAPANESE)
  path = [[NSBundle mainBundle] pathForResource:@"ja" ofType:@"lproj"];
  else if(app.currentLanguage==GERMAN)
  path = [[NSBundle mainBundle] pathForResource:@"de" ofType:@"lproj"];
  else if(app.currentLanguage==KOREAN)
  path = [[NSBundle mainBundle] pathForResource:@"ko" ofType:@"lproj"];
  else if(app.currentLanguage==RUSSIAN)
  path = [[NSBundle mainBundle] pathForResource:@"ru" ofType:@"lproj"];
  else if(app.currentLanguage==HINDI)
  path = [[NSBundle mainBundle] pathForResource:@"hi" ofType:@"lproj"];
  else if(app.currentLanguage==CHINESE)
  path = [[NSBundle mainBundle] pathForResource:@"zh-Hans" ofType:@"lproj"];
  else if(app.currentLanguage==ITALIAN)
  path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];
  else if(app.currentLanguage==PORTUGUESE)
  path = [[NSBundle mainBundle] pathForResource:@"pt" ofType:@"lproj"];
  else if(app.currentLanguage==THAI)
  path = [[NSBundle mainBundle] pathForResource:@"th" ofType:@"lproj"];
  else if(app.currentLanguage==MALAY)
  path = [[NSBundle mainBundle] pathForResource:@"ms" ofType:@"lproj"];
  else if(app.currentLanguage==INDONESIAN)
  path = [[NSBundle mainBundle] pathForResource:@"id" ofType:@"lproj"];
  else if(app.currentLanguage==CHINESE1)
  path = [[NSBundle mainBundle] pathForResource:@"zh-Hant" ofType:@"lproj"];
  else
  {
    path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
  }
  NSBundle* languageBundle = [NSBundle bundleWithPath:path];
  NSString* str=[languageBundle localizedStringForKey:key value:@"" table:@"LocalizeSTRING"];
  return str;
 }

Call this above method in didFinishLaunchingWithOptions of appDelegate.m

NSString *str=[[[NSUserDefaults standardUserDefaults]objectForKey:@"AppleLanguages"] objectAtIndex:0];

if([str isEqualToString:[NSString stringWithFormat: @"en"]])
{
    currentLanguage=ENGLISH;
    selectedrow=ENGLISH;
}
else if([str isEqualToString:[NSString stringWithFormat: @"ta-IN"]])
{
    currentLanguage=TAMIL;
    selectedrow=TAMIL;
}
else if([str isEqualToString:[NSString stringWithFormat: @"es"]])
{
    currentLanguage=SPANISH;
    selectedrow=SPANISH;
}
else if([str isEqualToString:[NSString stringWithFormat: @"fr"]])
{
    currentLanguage=FRENCH;
    selectedrow=FRENCH;
}
else if([str isEqualToString:[NSString stringWithFormat: @"ja"]])
{
    currentLanguage=JAPANESE;
    selectedrow=JAPANESE;
}
else if([str isEqualToString:[NSString stringWithFormat: @"de"]])
{
    currentLanguage=GERMAN;
    selectedrow=GERMAN;
}
else if([str isEqualToString:[NSString stringWithFormat: @"ko"]])
{
    currentLanguage=KOREAN;
    selectedrow=KOREAN;
}
else if([str isEqualToString:[NSString stringWithFormat: @"ru"]])
{
    currentLanguage=RUSSIAN;
    selectedrow=RUSSIAN;
}
else if([str isEqualToString:[NSString stringWithFormat: @"hi"]])
{
    currentLanguage=HINDI;
    selectedrow=HINDI;
}
else if([str isEqualToString:[NSString stringWithFormat: @"zh-Hans"]])
{
    currentLanguage=CHINESE;
    selectedrow=CHINESE;
}
else if([str isEqualToString:[NSString stringWithFormat: @"it"]])
{
    currentLanguage=ITALIAN;
    selectedrow=ITALIAN;
}
else if([str isEqualToString:[NSString stringWithFormat: @"pt"]])
{
    currentLanguage=PORTUGUESE;
    selectedrow=PORTUGUESE;
}
else if([str isEqualToString:[NSString stringWithFormat: @"th"]])
{
    currentLanguage=THAI;
    selectedrow=THAI;
}
else if([str isEqualToString:[NSString stringWithFormat: @"ms"]])
{
    currentLanguage=MALAY;
    selectedrow=MALAY;
}
else if([str isEqualToString:[NSString stringWithFormat: @"id"]])
{
    currentLanguage=INDONESIAN;
    selectedrow=INDONESIAN;
}

else if([str isEqualToString:[NSString stringWithFormat: @"zh-Hant"]])
{
    currentLanguage=CHINESE1;
    selectedrow=CHINESE1;
}

[self languageSelectedStringForKey:str];

Then in your Required View Controller

-(NSString*) languageSelectedStringForKey:(NSString*) key
{
  app=(AppDelegate *)[[UIApplication sharedApplication]delegate];
  if(app.currentLanguage==ENGLISH)
  path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
  else if(app.currentLanguage==TAMIL)
  path = [[NSBundle mainBundle] pathForResource:@"ta-IN" ofType:@"lproj"];
  else if(app.currentLanguage==SPANISH)
  path = [[NSBundle mainBundle] pathForResource:@"es" ofType:@"lproj"];
  else if(app.currentLanguage==FRENCH)
  path = [[NSBundle mainBundle] pathForResource:@"fr" ofType:@"lproj"];
  else if(app.currentLanguage==JAPANESE)
  path = [[NSBundle mainBundle] pathForResource:@"ja" ofType:@"lproj"];
  else if(app.currentLanguage==GERMAN)
  path = [[NSBundle mainBundle] pathForResource:@"de" ofType:@"lproj"];
  else if(app.currentLanguage==KOREAN)
  path = [[NSBundle mainBundle] pathForResource:@"ko" ofType:@"lproj"];
  else if(app.currentLanguage==RUSSIAN)
  path = [[NSBundle mainBundle] pathForResource:@"ru" ofType:@"lproj"];
  else if(app.currentLanguage==HINDI)
  path = [[NSBundle mainBundle] pathForResource:@"hi" ofType:@"lproj"];
  else if(app.currentLanguage==CHINESE)
  path = [[NSBundle mainBundle] pathForResource:@"zh-Hans" ofType:@"lproj"];
  else if(app.currentLanguage==ITALIAN)
  path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];
  else if(app.currentLanguage==PORTUGUESE)
  path = [[NSBundle mainBundle] pathForResource:@"pt" ofType:@"lproj"];
  else if(app.currentLanguage==THAI)
  path = [[NSBundle mainBundle] pathForResource:@"th" ofType:@"lproj"];
  else if(app.currentLanguage==MALAY)
  path = [[NSBundle mainBundle] pathForResource:@"ms" ofType:@"lproj"];
  else if(app.currentLanguage==INDONESIAN)
  path = [[NSBundle mainBundle] pathForResource:@"id" ofType:@"lproj"];
  else if(app.currentLanguage==CHINESE1)
  path = [[NSBundle mainBundle] pathForResource:@"zh-Hant" ofType:@"lproj"];
  else
  {
    path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
  }
  NSBundle* languageBundle = [NSBundle bundleWithPath:path];
  NSString* str=[languageBundle localizedStringForKey:key value:@"" table:@"LocalizeSTRING"];
  return str;
}

Call this above method in your viewDidLoad and viewWillAppear method or Call that method where you want to call

- (void)viewWillAppear:(BOOL)animated
{
  //If you want to set language in label,TextFiled
  localizeBackLabel.text=[self languageSelectedStringForKey:@"Back"];
  localizeDoneLabel.text=[self languageSelectedStringForKey:@"Done"];
  localizeTimeLabel.text=[self languageSelectedStringForKey:@"Time"];
  localizeDateLabel.text=[self languageSelectedStringForKey:@"Date"];

  //If you want to set language in button
  [yourButton setTitle:[self languageSelectedStringForKey:@"Back"]; forState:UIControlStateNormal];
  [yourButton setTitle:[self languageSelectedStringForKey:@"Done"]; forState:UIControlStateNormal];

   //If you want to set the Language in cell     
   cell.labelHomeList.text=[self languageSelectedStringForKey:@"Date"];
   cell.labelHomeList.text=[self languageSelectedStringForKey:@"Time"];
}

Finally if you want to change the language to other language.For example in (Settings) table you have two languages.If you want to change it to other languages please follow the below coding

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{  
   AppDelegate *app=(AppDelegate *)[[UIApplication sharedApplication]delegate];
   app.selectedrow=indexPath.row;
   if (indexPath.row==0)
   {
     app.currentLanguage=ENGLISH;
     [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"en", nil]forKey:@"AppleLanguages"];
     [[NSUserDefaults standardUserDefaults] synchronize];
      NSLog(@"%d", [[NSUserDefaults standardUserDefaults] synchronize]);
    }
    else 
    {
      app.currentLanguage=CHINESE1;
      [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"zh-Hant", nil]forKey:@"AppleLanguages"];
      [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

it works perfectly.

Solution 2:

use reloadData.

[YourUITableView reloadData];

and don't forget to save your language in a NSUserDefaults,

 [[NSUserDefaults standardUserDefaults] setValue:lang forKey:LANG];
 [[NSUserDefaults standardUserDefaults] synchronize];

so you can load your views and storyboards accordingly because when your tableView is reloaded, you can add your check for language to display the correct view in the cellForRowAtIndexPath method.

Edit.....

If you want to use NSNotification, register your observer in your viewDidLoad, as this

[[NSNotificationCenter defaultCenter] addObserver:self
                                      selector:@selector(updateLanguage:)
                                             name:@"updateLanguageObserver"
                                           object:nil];

and in your didSelectRowAtIndexPath add the listener

[[NSNotificationCenter defaultCenter] postNotificationName:@"updateLanguageObserver" object:self userInfo:nil];  

which will call your method updateLanguage where you can handle your localization and tableView reloading.

and don't forget in the viewController that adds the listener to remove observer as such

 - (void)dealloc {
     [[NSNotificationCenter defaultCenter] removeObserver:self];
 }