The officially recommended method for XIB/Storyboard localization is to create .xib and .storyboard files inside xx.lproj (where xx is the two letter language ID) for each localization you want to support.
This creates a problem because you have multiple files that in many cases share the same UI, that are prone to change. If you wanted to re-design the UI for one view, you'll have to do it multiple times (worse if you entered the localizable string values in the xib itself). This goes against the DRY principle.
It seems way more efficient to call NSLocalizedString()
where you need it, and just use one XIB or Storyboard for one base localization.
So, why should(n't) I create localized XIB/Storyboard files?
BUT, if you a professional developer, you MUST use xibs for VCs, Cells, etc, Because this is the only way to make them really reusable and portable, in order to gain so much time for the next project, or even when having to make a little change or build the storyboard again.
Right click on the xib file in Xcode, and choose Get Info . Select the General tab and on the bottom click Make File Localizable . Then you will be able to add localizations by clicking Add Localization on that same tab. I would recommend this tutorial for step-by-step information (and pretty pictures).
Storyboards - this is a visual tool for laying out multiple application views and the transitions between them (segues). XIBs (or NIBs) - each XIB file corresponds to a single view element and can be laid out in the Interface Builder, making it a visual tool as well.
You can make a category on UILabel, UIButton etc. like this:
#import "UILabel+Localization.h" @implementation UILabel (Localization) - (void)setLocalizeKey:(NSString*)key { self.text = NSLocalizedString(key, nil); } @end
and after that on your xib file use User Defined Runtime Attributes to link the UILabel (or UIButton etc.) to a key saved in your Localizable.strings file
This way you can have all your strings in one file and you do not have to create a separate xib for each language.
For just changing text labels I did something like this
+(void) replaceTextWithLocalizedTextInSubviewsForView:(UIView*)view { for (UIView* v in view.subviews) { if (v.subviews.count > 0) { [self replaceTextWithLocalizedTextInSubviewsForView:v]; } if ([v isKindOfClass:[UILabel class]]) { UILabel* l = (UILabel*)v; l.text = NSLocalizedString(l.text, nil); [l sizeToFit]; } if ([v isKindOfClass:[UIButton class]]) { UIButton* b = (UIButton*)v; [b setTitle:NSLocalizedString(b.titleLabel.text, nil) forState:UIControlStateNormal]; } } }
call this function in your viewDidLoad:
like this:
[[self class] replaceTextWithLocalizedTextInSubviewsForView:self.view];
It saved me a lot of work declaring and connecting IBOutlets when all you want is localized labels.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With