How to Localize Label Strings in iOS for a Beginner

How to localize label strings in iOS for a beginner?

For localization, you need to do:

  1. Add different .strings file for each language
  2. Add the Key value for each language file
  3. Use:

NSLocalizedString(yourKey, nil);

or

[[NSBundle mainBundle] localizedStringForKey:(yourKey) value:@"" table:nil]

For getting the localized string of passed key.

Tutorials:


  1. Localization in iOS apps made simple
  2. iPhone Apps Localization Guide
  3. Preparing your iOS app for localization in Xcode

iOS localization, label with number and word together

Yes, you can do this. It looks like this (uncompiled; hopefully there is no typo):

NSString *scoreFormat = NSLocalizedString(@"Score: %d", @"Score format");
NSString *scoreString = [NSString stringWithFormat:scoreFormat, bestScore];

Your strings file for this in English would be:

/* Score format */
"Score: %d" = "Score: %d";

There is no difference between %d and %i. They are both specified by the standard. I personally prefer to express that it is "decimal" (vs. %x hexadecimal) rather than that it is an "integer" (vs. %f float). But it does not matter.

You should include the entire format statement in the strings file. You are localizing the entire format statement Score: %d. The rationale for this is to permit languages where the order might be different. For example, if there were a language where the correct translation were "%d score" or a language where to make sense you would have to say the equivalent of Score: %d points or Score: %d number.

If you don't want this kind of localization, and you will always put a colon after the label and a number after that, no matter the language, then you can localize just the label as you were in your original code, or like this:

NSString *localizedLabel = NSLocalizedString(@"Score", @"Score");
NSString *scoreString = [NSString stringWithFormat:@"%@: %d", localizedLabel, bestScore];

You should avoid calling NSLocalizedString with a variable parameter as you're suggesting. This is confusing, and can get in the way of using genstrings to create your strings file. That said, the following code is not a problem:

NSString * const kScoreLabelKey = @"Score";
NSString * const kPriceLabelKey = @"Price";

NSString *GetLocalizedStringForKeyValue(NSString *key, NSInteger value)
{
NSString *label = [[NSBundle mainBundle] localizedStringForKey:key value:nil table:@"Labels"];
NSString *valueLabel = [NSString stringWithFormat:@": %d", value];
return [label stringByAppendingString:valueLabel];
}

...

NSString *label = GetLocalizedStringForKeyValue(kScoreLabelKey, bestScore);

...

(In Labels.strings):

"Score" = "Score";
"Price" = "Price";

Things to note:

  • I created a separate strings file for this called Labels.strings. That way it doesn't impact using genstrings and the main Localizeable.string.
  • I used string constants for the keys. That puts all the strings used in one place at the top of the file, making it easy to audit against Labels.strings.

Label in storyboard don't take the right localization value

Since storyboards elements ids changes and they are not managable to be used as "keys" in your localized "key-value" pair one better solution when localizing storyboards (UI) elements could be to provide a custom User Define Attribute defined as a Locale Key to be used for that UIView.

Then you can define in your Storyboard Attribute Inspector for a specific UI View an input field that will be filled with the localized key defined in your Localizable.strings files (one for English one will be for Swedish, both should have the same keys but with different values - in the English one will have english translations in values, and in Swedish one the opposite.

1) For example since you want to localize a UI View UILabel than you can have this in a swift file Localizable.swift for example (the code makes possible:

import UIKit

// MARK: Localizable
public protocol Localizable {
var localized: String { get }
}

extension String: Localizable {
public var localized: String {
return NSLocalizedString(self, comment: "")
}
}

// MARK: XIBLocalizable
public protocol XIBLocalizable {
var localeKey: String? { get set }
}

extension UILabel: XIBLocalizable {
@IBInspectable public var localeKey: String? {
get { return nil }
set(key) {
text = key?.localized
}
}
}

2) You can uncheck your storyboard translations so you will endup having 1 storyboard without duplicating the storyboard into multiple translated version.

3) You can create now a Localizable.strings file containing your keys and translations and localize this file in order to have your translations (as you did with the storyboard, but instead of localizing the storyboard into multiple translated version, you will localize the Localizable.strings file (so you will see two files after you localize that in both languages, one will be called Localizable.strings (English) and the other Localizable.strings (Swedish).

Your Localizable.strings (English) could look like this for example:

"main_page_title_label" = "Main Page Title in English";

Your Localizable.strings (Swedish) could look like this for example:

"main_page_title_label" = "Huvudsida Titel på engelska";

4) Now go to your LaunchScreen.storyboard which you should have un-localized so you only have one version of it and not two like in your example pictures (English, Swedish). Look for the UILabel you want to localize and under the Attribute Inspector you will see a new input field called Locale Key here you can put as a value main_page_title_label. And now you have just localized a UILabel in your storyboard.
Sample Image

5) To test it from the simulator you have to change the language in Edit Scheme > Run > Options > Application Language and after you save it you can now run the app in the simulator and it will simulate that your simulator OS system will be set to Swedish language, so the label set with that key will show the Swedish value for that key.
Sample Image

Supporting more UI Views (UIButton, UITextField, UISearchBar..)

If you want to be able to localize more UI View, and not just UI View of type UILabel than you can add more support to the Localizable.swift file.

If you want to be able to localize also a UI View of type Button you can add this to Localizable.swift:

extension UIButton: XIBLocalizable {
@IBInspectable public var localeKey: String? {
get { return nil }
set(key) {
setTitle(key?.localized, for: .normal)
}
}
}

To support localization in storyboards for UITextField and UISearchBar placeholder text add this to your Localizable.swift:

// MARK: Special protocol to localizaze UI's placeholder
public protocol UIPlaceholderXIBLocalizable {
var localePlaceholderKey: String? { get set }
}

extension UITextField: UIPlaceholderXIBLocalizable {

@IBInspectable public var localePlaceholderKey: String? {
get { return nil }
set(key) {
placeholder = key?.localized
}
}

}

extension UISearchBar: UIPlaceholderXIBLocalizable {

@IBInspectable public var localePlaceholderKey: String? {
get { return nil }
set(key) {
placeholder = key?.localized
}
}

}

Swift: Localization in Storyboard - Labels not added to Main.strings?

After selecting UILabel from storyboard, You can find object id of UILabel in right panel:

Sample Image

Then you can set text of label as below in your Main.string file:

"sxl-NO-5WX.text" = "Phone";

How to localize an accessibility label

The answer to your question is that the WHOLE nib (or xib, actually) is meant to be localized per language. There's one xib for English, one for Spanish, one for Japanese, etc.

UiTextView localized with xib strings file

I've found the following workaround until Apple fixes this (serious) bug that still exists in iOS 7 :

You actually need to 'mix' the 'base localisation method' (= preferred method for Xcode 5 & iOS 7) with the 'older' method of using the 'Localizable.strings' file

1) create the file 'Localizable.strings' (File -> New -> iOS -> resource -> .strings file)

2) use Xcode to create localised versions of this file for each language you use (select the file 'Localizable.strings', in File Inspector under 'Localization' click on the selection button next to each language you use).

3) in your viewController create an IBOutlet @property for the UITextField :

@property (weak, nonatomic) IBOutlet UITextView *localizedTextView;

4) under 'viewDidLoad' add the following code :

self.localizedTextView.text = NSLocalizedString(@"textFieldKey", @"comment for the translator");

5) in each 'Localizable.strings' file add :

"textFieldKey" = "the translated text you want to be put in the textField";

That should do it !

Keep in mind that Apple will probably fix this bug somewhere in the near future, in that case the translation will be taken from the 'base localised storyboard' (the one with the object references in, like "a8N-K9-eJb.text" = "some translated text". In that case you can delete the 'Localization.strings' file, and use base localisation again for a UITextField

iOS is there a way to assign Localized String to a UILable from IB/storyboard

Just select your storyboard/xib, go to File Inspector. In the Localization part, you can tick the language you want. Then, it will create a .string file with all text used in storyboard. You'll just have to provide a translation for each text used in storyboard.

If no language appear in this part, you have to change values of Localization native development region in Info of your project.

How to handle partially translated Localizable.strings file

I find the easiest way to cope with this is to use the default string as the key. So you might have:

Base:

"Hello World" = "Hello World"; 
"Hello World 2" = "Hello World 2";

Chinese:

"Hello World" = "Hello World in Chinese";

If you haven't made any translations you just need to have at least one placeholder string in the file to avoid a compilation error, e.g. for a double space:

Russian:

/* Placeholder */
" " = " ";

It also makes the translator's job much easier!



Related Topics



Leave a reply



Submit