Kevlar
Kevlar

Reputation: 8924

IPhone localization: Is it possible to translate nib files easily without having to copy the nib for each language?

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

Answers (6)

pre
pre

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

Ricibald
Ricibald

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

rpetrich
rpetrich

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

bdunagan
bdunagan

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

Marco
Marco

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

Lyndsey Ferguson
Lyndsey Ferguson

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

Related Questions