Reputation: 8924
I'm trying to find a manageable way to translate every visible string in an iPhone application. The official apple documentation says to use .strings files for programmatic strings, while using the built in "add localized file" option in xcode to localize nib files.
The problem i see with this is that if the UI needs to change after localization happens, then we would need to update the nibs for each language individually which is less than optimal. Is there a simpler way to perhaps tie strings displayed in nib files to relevant values in a .strings file? or would i have to programmatically have to set those strings for each ui element (which is slightly better but still annoying)?
Upvotes: 10
Views: 6492
Reputation: 3506
I always set all strings needed in the viewDidLoad() method with only having placeholders in the .xib. This way I can localize any .xib easily with only updating .string files
Upvotes: 0
Reputation: 9939
You can localize automatically your nibs without duplicating them following this simple guide:
http://programminghacks.net/2011/06/03/ios-nib-localization-in-localizable-strings/
Upvotes: 1
Reputation: 32326
The best you can do is recursively loop through each view and then set the text on them:
static void translateView(NSBundle *bundle, UIView *view)
{
id idView = view;
if ([idView respondsToSelector:@selector(text)] && [view respondsToSelector:@selector(setText:)])
[idView setText:[bundle localizedStringForKey:[idView text] value:nil table:nil]];
if ([idView respondsToSelector:@selector(title)] && [view respondsToSelector:@selector(setTitle:)])
[idView setTitle:[bundle localizedStringForKey:[idView title] value:nil table:nil]];
if ([idView respondsToSelector:@selector(placeholder)] && [view respondsToSelector:@selector(setPlaceholder:)])
[idView setPlaceholder:[bundle localizedStringForKey:[idView placeholder] value:nil table:nil]];
if ([idView respondsToSelector:@selector(prompt)] && [view respondsToSelector:@selector(setPrompt:)])
[idView setPrompt:[bundle localizedStringForKey:[idView prompt] value:nil table:nil]];
if ([idView respondsToSelector:@selector(titleForState:)] && [view respondsToSelector:@selector(setTitle:forState:)])
[idView setTitle:[bundle localizedStringForKey:[idView titleForState:UIControlStateNormal] value:nil table:nil] forState:UIControlStateNormal];
if ([idView isKindOfClass:[UITabBar class]] || [idView isKindOfClass:[UIToolbar class]])
for (UIBarItem *item in [idView items])
[item setTitle:[bundle localizedStringForKey:[item title] value:nil table:nil]];
for (UIView *subview in [view subviews])
translateView(bundle, subview);
}
Warning: You may of have to check other sets of selectors to catch everything. This is not a best-practice, but it seems like much less work
Upvotes: 3
Reputation: 1212
Apple's built-in command line program ibtool lets you do this. You can dump the strings from a XIB, localize them, then create a new XIB based on the existing XIB but using the localized strings. So you can always have a base set of XIBs and recreate them all whenever the localized strings change. More info here: http://www.bdunagan.com/2009/03/15/ibtool-localization-made-easy/.
Upvotes: 15
Reputation: 779
Perhaps you should update every string manually. Let's say you have an array, or an xml file, of strings in different languages, when the user changes the language just get the translated string from the array and then change it to the UI.
Marco
Upvotes: 0
Reputation: 5384
I think you want to read about the command line tool: ibtool. It should simplify what you're looking to do.
Upvotes: 2