There's some discussion of other approaches here, in particular a notification based approach:
iOS: How to change app language programmatically WITHOUT restarting the app?
In my view there are really three tasks here:
(1) re-localization of resources automatically loaded from nibs. (for example if you dynamically instantiate another custom UIView from a nib, the "old" language strings and settings (images, text direction) will still be loaded)
(2) re-localization of strings currently displayed on the screen.
(3) re-localization of strings inserted by the developer (you) in program code.
Let's start with (3). If you look for the definition you will notice that NSLocalizedString is a macro. So if you don't want to change existing code too much, you can probably solve the problem of (3) by creating a new header file. In that header file, #undef
and then re-#define NSLocalizedString
to pick the localized string from the appropriate place--not the one that iOS defaults to, but one that you keep track of in some global variable (e.g., in an app delegate ivar). If you don't want to redefine NSLocalizedString but you still make your own alternative , you should probably still #undef NSLocalizedString
if you don't want future developers to accidentally call it instead of the macro you replace it with. Not an ideal solution, but maybe the most practical.
As for (1), if you haven't done your localization in Interface Builder, but rather you do it dynamically in viewDidLoad, etc., no problem. You can use the same behavior just discussed (i.e., the modified NSLocalizedString, etc.). Otherwise you can either (a) implement a notification system as described in the link above (complicated), or (b) consider moving localization from IB to viewDidLoad, or (c) try overriding initWithNibName:
and swap out the object loaded with the old language resources, with one loaded with the new language resources. This was an approach mentioned by Mohamed at the very bottom of this discussion: http://learning-ios.blogspot.ca/2011/04/advance-localization-in-ios-apps.html. He claims it causes problems (viewDidLoad isn't called). Even if it doesn't work, trying it out might point you towards something that does.
Finally, (2) is presumably the easiest task: just remove and re-add the current view (or in some cases, just redraw it).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…