iOS - change language for user via buttons -


im making interactive children's story uses custom graphics , narrations.

i have graphics in both english , spanish.

i dont have non-custom buttons, no text fields, not single "standard" apple app ui element anywhere. custom png file.

im looking method allow user change english spanish or vice-versa.

i created custom english , spanish button already, highlight when pressed.

the app (from ive read need restarted) , app present spanish pages (and spanish text embedded in png). spanish narration ensue.

at point user can elect hit english language button, , return english if desired.

tabtale's "mermaid princess" app extremely well, , far more need, example of im after. click button, change region, app restarts, , custom text , narrations result region youve selected.

i have 2 regions (languages) need simpler.

but how in world pull off ?

cheers !

ok, harder had expected…


basically exchanging nsbundle's method invoked nslocalizedstring(…) using category on nsbundle , technique called isa-swizzeling


nsbundle+language.h

#import <foundation/foundation.h>  @interface nsbundle (language) +(void)setlanguage:(nsstring*)language;  @end 

nsbundle+language.m

#import "nsbundle+language.h" #import <objc/runtime.h>  static const char associatedlanguagebundle=0;  @interface privatebundle : nsbundle @end  @implementation privatebundle -(nsstring*)localizedstringforkey:(nsstring *)key                             value:(nsstring *)value                             table:(nsstring *)tablename {     nsbundle* bundle=objc_getassociatedobject(self, &associatedlanguagebundle);     return bundle ? [bundle localizedstringforkey:key                                             value:value                                             table:tablename] : [super localizedstringforkey:key                                                                                       value:value                                                                                       table:tablename]; } @end  @implementation nsbundle (language) +(void)setlanguage:(nsstring*)language {     static dispatch_once_t oncetoken;     dispatch_once(&oncetoken, ^{         object_setclass([nsbundle mainbundle],[privatebundle class]);     });      objc_setassociatedobject([nsbundle mainbundle], &associatedlanguagebundle, language ?                              [nsbundle bundlewithpath:[[nsbundle mainbundle] pathforresource:language oftype:@"lproj"]] : nil, objc_association_retain_nonatomic); } @end 

the appdelegate listen language_will_change notifications, set language , broadcast notification language_did_change

appdelegate.m

#import "appdelegate.h" #import "nsbundle+language.h"  @interface appdelegate ()  @end  @implementation appdelegate   - (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {     [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(languagewillchange:) name:@"language_will_change" object:nil];      nsstring *targetlang = [[nsuserdefaults standarduserdefaults] objectforkey:@"selectedlanguage"];     [nsbundle setlanguage:targetlang?:@"en"];     return yes; }  -(void)languagewillchange:(nsnotification *) noti {     nsstring *targetlang = [noti object];     [[nsuserdefaults standarduserdefaults] setobject:targetlang forkey:@"selectedlanguage"];      [nsbundle setlanguage:targetlang];      [[nsnotificationcenter defaultcenter] postnotificationname:@"language_did_change" object:targetlang]; }   @end 

a baseviewcontroller post language_will_change , listen language_did_change


baseviewcontroller.h

#import <uikit/uikit.h>  @interface baseviewcontroller : uiviewcontroller -(void) languagedidchange; - (ibaction)switchlanguage:(id)sender; @end 

baseviewcontroller.m

#import "baseviewcontroller.h"  @interface baseviewcontroller () @property (weak, nonatomic) iboutlet uibutton *englishbutton; @property (weak, nonatomic) iboutlet uibutton *spanishbutton;  @end  @implementation baseviewcontroller  - (void)viewdidload {     [super viewdidload];     [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(languagedidchangenotification:) name:@"language_did_change" object:nil]; }  - (ibaction)switchlanguage:(id)sender {      nsstring *localstring;     if (self.englishbutton == sender) {         localstring = @"en";     } else if(self.spanishbutton == sender){         localstring = @"es";     }      if (localstring) {         [[nsnotificationcenter defaultcenter] postnotificationname:@"language_will_change" object:localstring];     } }  -(void)languagedidchangenotification:(nsnotification *)notification {     [self languagedidchange]; }  -(void)languagedidchange {  }  @end 

now view controller subclasses baseviewcontroller can implement languagedidchange call nslocalizedstring.


viewcontroller.m

#import "viewcontroller.h"  @interface viewcontroller () @property (weak, nonatomic) iboutlet uilabel *label; @property (weak, nonatomic) iboutlet uiimageview *imageview; @end  @implementation viewcontroller  - (void)viewdidload {     [super viewdidload];     [self languagedidchange]; }   -(void)languagedidchange {     self.label.text = nslocalizedstring(@"hello world", nil);     self.imageview.image = [uiimage imagenamed:nslocalizedstring(@"image.png", nil)]; }  @end 

ad see, localising image name, added images en_image.png , es_image.png images asset bundle , map them in localizable strings

"image.png" = "en_image.png"; 

and

"image.png" = "es_image.png"; 

result

enter image description here


you'll find example code here: https://github.com/vikingosegundo/immidiatelanguagechange


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -