Can i link a uilabel to a localizable string in Interface Builder?
Asked Answered
P

9

18

have googled around but found no solution:

Basically, i have a Localizable.strings set up, which i'm using in my code. However, it would be really sweet if i somehow could just refer those values in my XIB's too, so that i can avoid having to create one annoying XIB per language...

Is this possible?

Pruinose answered 14/9, 2011 at 8:54 Comment(1)
If you think (like I do) that localizing your IB files with ibtool or by linking your components in code is complex, check out this library: github.com/angelolloqui/AGi18n It just adds some magic to translate all elements on runtime, totally transparent for the developer, and also provides a few commands to extract the labels from your IB files into the Localizable.strings for each language. DISCLAIMER: I am the developer of the librarySabbatarian
N
18

You could implement a subclass of UILabel and have it automatically pull the localized value when it's initialized from the nib. In the XIB you would then just set the token (or english text if you prefer) and have UILabel pull the localized text from this value.

Norge answered 14/9, 2011 at 9:1 Comment(4)
one subclass of UILabel per localizable label I might have in my app? That sounds a little overkill to me :-SBeeck
@Jonathan, I think you did not get what Claus was proposing : You should only do one UILabel subclass, which in awakeFromNib will get the text you've set the label to, and use it as the key to get the localized string automatically. I just implemented it and it works perfectly. This should really be the accepted answer !Omalley
Base internationalisation provides a way to avoid subclassing UILabel for localisation purposes.Lubricious
I think this is more accurate: rshankar.com/…Brantbrantford
Y
16

I present to you the swifty way

1. Create a subclass of UILabel

class LozalizedLabel : UILabel {

    @IBInspectable var keyValue: String {
        get {
            return self.text!
        }
        set(value) {
            self.text = NSLocalizedString(value, comment: "")

        }
    }
}

2. Set the class to be LocalizedLabel in IB

enter image description here

3. Enter your key from Localizable.strings directly in IB

enter image description here

Voila, now spend less time on creating useless IBOutlets just for making it a localizable UILabel.

NOTE This does not make the localized string show in the interface builder, but rather just the "key". So when building your TextView's remember to set constraints accordingly

Yi answered 31/8, 2017 at 12:52 Comment(0)
T
5

There is no way to set then from the Localizable.strings directly with Interface Builder.

The reason you might want to translate the NIB is because the length of the words may vary in each language. Thus allowing you to change the layout of you nib per language.

What you could set them in the viewDidLoad method of your UIViewController.

- (void) viewDidLoad {
   [supper viewDidLoad];

   self.someLabel.text = NSLocalizedString(@"Some Label", @"Some label on some view.");
}
Twostep answered 14/9, 2011 at 8:57 Comment(4)
Thats what i am doing, just wondered if there is a better way. Have to say that Android dev env setup is way ahead in this department. Ah well...Pruinose
Alternatively, if you don't want to have IBOutlets for each of your labels just for the sake of translations, you can use tags instead.Seriatim
There is a better way. Check out my answerSabbatarian
Obsolete answer. You'll want to use Base internationalisation with auto-layout constraints.Lubricious
H
5

NSLocalizedString has the advantage of being easy to implement. Risk is that you might forget to add an entry for a new Gui element.

You can use itool to dump the string from the original xib file, translate these dumped strings and then load the translated string into the other-language-xib file.

There are some advantages doing it this way compared to NSLocalizedString.

  • All the consideration for translation and string length still apply but you need to touch only the original xib, the other languages can be updated by script.
  • You see the elements already translated and the different possible states for each UIElement from the dumped file.
  • You will have more single strings files to send to your translator but it is easier to keep an overview as to what part is in need of translation, what part is done.
  • GUI Changes done to the english xib are applied to the localized xib, you are basically merging the original xib with the translated strings.

When you create a XIB you set it to being localized (as before), then run itool against this original xib to extract the strings. Translate the strings file into the desired language then load the translation into the localized xib.

If you google for ibtool --generate-strings-file you should find a few tutorials and examples.

The syntax should be similar to:

  #dump original xib to a $xibfile.strings file:
  ibtool --generate-strings-file Resources/English.lproj/$xibfile.strings Resources/English.lproj/$xibfile.xib
  # offline: translate the $xibfile.xib, place it into the correct lproj folder
  # then: merge translated $xibfile.strings with original xib to create localized xib
  ibtool --strings-file Resources/de.lproj/$xibfile.strings --write Resources/de.lproj/$xibfile.xib Resources/English.lproj/$xibfile.xib

$xibfile.strings in the Resources/English.lproj directory will contain the original (English language) strings. The translated $xibfile.strings must go in the appropriate xx.lproj directory.

If you add a buildscript to xcode then the loading of the translation will be called at each build.

Herminiahermione answered 14/9, 2011 at 10:24 Comment(0)
P
4

IB cannot use strings from Localizable.strings, but there is another option called Base Internationalization.

In short: you can create separate .strings file attached to the xib/storyboard for every required language. In the result you will have xib with it's own translations for each language. So it can duplicate some of the values that you have in Localizable.strings, but it's more clear way than setting through the code or copying xib files.

Please refer to the Apple Documentation about Base Internationalization.

Pounce answered 5/1, 2015 at 18:8 Comment(1)
That duplication cannot be avoided at all? I am a noob at iOS, and I find Android's solution to this problem much more elegant. If you localise the storyboard, the launch screen and keep a .strings file, you could potentially have the same strings 3 times. DRY failure right there.Commeasure
T
3

Another swifty way, but with extension :

extension UILabel {
    static var localizedKey:UInt8 = 0

    @IBInspectable public var localizationKey: String? {
        set {
            objc_setAssociatedObject(self, &UILabel.localizedKey, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
        get {
            return objc_getAssociatedObject(self, &UILabel.localizedKey) as? String
        }
    }

    open override func awakeFromNib() {
        super.awakeFromNib()
        if let localizationKey = self.localizationKey {
            self.text = NSLocalizedString(localizationKey, comment: "")
        }
    }
}

You will then be able to write the localization key directly from IB, and it will be localized at runtime.

Toulouse answered 28/2, 2018 at 14:26 Comment(0)
S
1

You can do this in code:

    label.text = NSLocalizedString(@"key", @"comment");

But I don't think there is a way to do it with just nibs other than localizing the entire nib. I've certainly not found another way in the past.

Sassanid answered 14/9, 2011 at 8:56 Comment(2)
What makes you say that? This is still possibleSassanid
"I don't think there is a way to do it with just nibs other than localizing the entire nib" is wrong.Lubricious
M
1

This is my version. Hope it helps.

extension UILabel {

    /// The IBInspectable helps us to set localizable text in IB
    @IBInspectable var localizableText: String? {
        get { return text }
        set(value) { text = value?.localized() }
    }


    /// The IBInspectable helps us to set localizable text in IB
    @IBInspectable var localizableUppercaseText: String? {
        get { return text }
        set(value) { text = value?.localized().uppercased() }
    }
}

extension String {

    func localized(bundle: Bundle = .main, tableName: String = "Localizable") -> String {
        return NSLocalizedString(self, tableName: tableName, value: "**\(self)**", comment: "")
    }

}
Mandolin answered 6/11, 2018 at 11:29 Comment(0)
P
0

The Apple-supported way to the localize the .xib file. This allow you to localize the text and layout for each language/country.

enter image description here

Phlebosclerosis answered 14/5, 2015 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.