UiTextView localized with xib strings file
Asked Answered
P

13

26

I use base internationalization in xCode to manage multiple languages in my app.

In a xib file I've got this object :

Xrj-9E-2VK it's an UITextView

In the corresponding strings file :

"Xrj-9E-2VK.text" = "text translated in french"

But my text is still in English.

Any Suggestion ?

Parenteral answered 17/10, 2013 at 12:11 Comment(12)
Try this #16418225Flimsy
Remove the app from the simulator or device and see if that changes anything. I had many localization problems that happened because Xcode does not delete files during deployment.Parallelogram
Senthil : I would not use NSLocalizedString maccro but the string file generate for the XIB file. MatthiasBauch : I try but but I've still the problem.Parenteral
I'm having this issue as well. Everything in my Storyboard is localizing properly except the lone UITextView I have.Glamorous
Try to put the translation like "Xrj-9E-2VK.text" = "text translated in french" in your file Localizable.strings. It worked for me.Parenteral
looks like a bug to me ... no way to solve itRegelate
It's Jun 2014, and still a bug.Kimberlykimberlyn
This bug still exists in XCODE 6 & IOS 8...Materiality
Still appears to be a problem even in storyboards in Xcode 7.2.1 and iOS 9.2.Candiot
Hello from 2017, bug is still there in Xcode 8.3.2. Submitted a bug report, so clearly it will be fixed now. Right?Shandeigh
It still exists in iOS 13. Unbelievable!Kingpin
I finally found the reason. there was missing semicolon character one of the lines. I've putted that semicolon and problem fixedScapolite
R
11

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

Regelate answered 2/2, 2014 at 16:38 Comment(8)
I want to complete your answer and mention that base localisation method and 'older' method of using the Localizable.strings is a mutually complementary. Localizable.strings files is used for in code strings such as alerts and etc. etc.Sheree
Wow, it's May and Apple still haven't fixed this.Hindbrain
You can simply use NSLocalizedStringFromTable and save the trouble of moving the strings to Localizable.strings.Kimberlykimberlyn
This does not seem to work somehow, see my answer for a workaroundWilsey
Hello Gabriel Cartier, I must say that this method is working in my 2 Apps which are in the App Store since 15 months, even after my recent update using the latest XCode 6 and iOS 8. The app works perfectly in 2 languages. Not sure what you did differently? Can you clarify what did not work?Regelate
See my answer. You can't change the a UITextView with setText unless your textview is not an attributed text. In which case, you need to use the setAttributedText method. The answer suggests that you simply need to set the text which most of the time wouldn't work because using UITextView, in my opinion, seems to be mainly for attributed text.Wilsey
Two years passed, iOS 7, 8 and 9 and the bug is still there. Apple don't give a crap.Candide
Seven years later, still there.Daigle
M
7

This still appears under Xcode 6 & IOS 8, and the previous answers don't satisfy me.

Here's my simple and quick workaround :

  1. Select the XIB and then in the file inspector
  2. Below "Localization", find the language that does not work
  3. Change "Localizable Strings" to "Interface Builder Cocoa Touch XIB"

XCODE XIB inspector file screenshot

  1. Run the app, the translation should be ok now !

You can then go back to "Localizable Strings" if you prefer... In this case please note that you must run at least once the app with the "Interface Builder Cocoa Touch XIB." option selected.

Materiality answered 6/10, 2014 at 17:41 Comment(6)
Thank you, this has worked for me in Xcode 6.1.1 and iOS 8.1.Cathryncathy
Works for me until I clean the build target and build again... Had to fall back to regular localization :/ It's ridiculous that this bug still exists after so long.Valma
You rock dude! After hours, this fixed my problem.Luxembourg
This isn't a real fix. It's working because the translated XIB is sticking around in your deployed copy of the app on the device and iOS is favoring it over the strings file. If you delete the app from the device and clean your workspace it will be broken again (which is what happens when you archive your app for the app store).Hebraist
This is working great. But to make this fix last, you should not switch back to "Localizable Strings" but stick with the xib.Tharpe
Very Bad Fix, It removed all Translations i entered before.Recessive
O
6

You can use NSLocalizedStringFromTable to retrieve the texts as generated by xcode's IB as follows, in viewDidLoad:

self.intro_text.text = NSLocalizedStringFromTable(@"2Vy-59-WN8.text", @"Main", @"");

Where 2Vy-59-WN8.text is the generated key you can find in the Main.strings for the UITextView.

BTW: this is an xcode/IB bug, not an iOS bug.

Oiler answered 22/2, 2015 at 18:4 Comment(1)
I don't recommend hardcoding the text via hardcoded id generated by interface builder, it could change. You are better off extracting the base string and setting it via NSLocalizedString.Kahaleel
S
4

If you want to use the existing MainStoryboard.strings file you can programmatically assign the text of your textview using localizedStringForKey:value:table: like this

[[NSBundle mainBundle] localizedStringForKey:@"abc-12-3ba.text" value:@"" table:@"MainStoryboard"]

Shillelagh answered 8/12, 2017 at 21:52 Comment(0)
P
2

This is my Swift 2 answer:

We don't want to repeat the fix in each UIViewController, so let's start with an extension:

import UIKit

extension UIViewController {

    // if the property "Selectable" = NO it will reset the font and fontcolor when setText is used.
    // So turn Selectable ON 
    func localizeUITextViewsFromStoryboard(storyboardName: String) {
        for view in self.view.subviews {
            if let textView = view as? UITextView,
                let restorationIdentifier = textView.restorationIdentifier {
                let key = "\(restorationIdentifier).text"
                let localizedText = NSLocalizedString(key, tableName: storyboardName, comment: "")
                if localizedText != key {
                    textView.text = localizedText
                }

            }
        }
    }

}

In each UIViewController where we need this fix, we write

override func viewDidLoad() {
    super.viewDidLoad()
    self.localizeUITextViewsFromStoryboard("Main")
}

This code uses the restoration ID of the UITextViews. This means the we need to copy the Object ID to the restoration identifier in the storyboard for each UITextView.

Ponceau answered 24/12, 2015 at 12:14 Comment(0)
M
1

I got this to work with Xcode 5.1.1 and iOS7.

Select the ViewController you want to localize in the left file panel. In the right panel select the File Inspector.

You will see a "Localize..." button. Tap the button. You will be presented with a drop down list of languages you can select from. Select Base and then tap "Localize".

In the right panel the Localization section will now have "Base" selected and your other languages will be listed. Select the languages you want to support. Leave the "native" language of your app unchecked.

There are definitely caching issues. I have found that changes only appear sometimes after I have deleted the app from simulator and when I delete Xcode's derived data.

Manhour answered 29/5, 2014 at 16:20 Comment(0)
O
1

File a bug with Apple. Let them know this is happening, and causing you (and me) time and frustration. This whole localization system is not there to have us fall back to NSLocalizedString..

Oiler answered 22/2, 2015 at 17:38 Comment(1)
This bug is two years old. Apple know about it. Apple don't give a crap.Candide
W
0

UPDATE

The best way to actually change the text is to directly use the setter from the UITextView.

If your text is NOT formatted, simply use:

[textView setText:NSLocalizedString(key, comment)];

If your text IS formatted, you have to use:

[textView setAttributedText:[[NSMutableAttributedString alloc] initWithString:NSLocalizedString(key, comment)]];

You don't need to use the workaround anymore with the updated method.

WORKARROUND

To be able to achieve this, the easiest solution I have found is to simply add an extra UITextView with the translated text exactly at the same place as the other and hide it.

To display the proper view I do this in the viewDidLoad method of the controller:

NSString *language = [[NSLocale preferredLanguages] firstObject];
if ([language isEqualToString:FRENCH_LANGUAGE]) { //@"fr"
    UITextView.hidden = YES;
    UITextViewFR.hidden = NO;
}

Although this solution is definitely not elegant, it's certainly a good workaround when you don't have to keep a lot of translations.

That being said, using the storyboard localized string is not working. Adding an IBOutlet and setting the text attribute with a NSLocalizedString was not working too. I have looked around for a solution and it seems like no one has really been able to find a clear answer for that one.

Wilsey answered 15/7, 2014 at 22:16 Comment(3)
Technically, there is no way this solution does not work, you have two views and hide one based on the locale. Either validate that you go in the IF based on the locale or don't.Wilsey
I agree that technicaly this could work, but what would you do if you need to support 20 languages? you'd need to modify your code each time you add a language. Try setting up autolayout with 20 textViews layered on top of each other, it will be a nightmare. The whole purpose of decouping translations from your view is gone if you go this way. I would not recommend it. Translations should be completely decoupled from your UIRegelate
Yea I mentioned that it was actually not a viable solution. I had updated my post too, with the method [textView setAttributedText:[[NSMutableAttributedString alloc] initWithString:NSLocalizedString(key, comment)]]; it is actually fairly simple. The problem is that the accepted answer does not work since a long time ago.Wilsey
G
0

Xcode 7 still seems buggy...

Before trying anything complicated try these 3 simple steps:

  1. Delete the app from the device (not the simulator)
  2. Product -> Clean
  3. Run on device

Good luck.

Garold answered 14/6, 2016 at 5:49 Comment(0)
S
0

This issue still occurs in Xcode 11.5. I have decided to use UILabel instead and the localised text is being picked up as expected. This is an easy workaround when you keep static text in the view. Just remember to set maxLines to a higher number.

Sensillum answered 12/7, 2020 at 10:41 Comment(0)
S
0

I finally found the reason. there was missing semicolon character one of the lines. I've putted that semicolon and problem fixed

Scapolite answered 28/8, 2020 at 14:48 Comment(0)
G
0

I'm having trouble loading translations in XCode 15

I looked for answers on the pages:

It turned out that the files LANG_CODE.lproj/Main.strings are not included in the final assembly. I tried copying these files manually and the translations worked.

I realized that the problem is in XCode itself. It turned out that this was an old bug. After clearing the cache, after the 5th try it worked in one of the applications. By the way, Apple itself considers this localization method obsolete and, unfortunately, all the documentation promotes this particular method.

I did not investigate why this file is not included in the assembly. Also, loading translations via code seemed like a disgusting idea to me. I would only do the loading via code if it were formatters or plural translations...

Instead, I discovered a great option called "Migrate to String Catalog". The files LANG_CODE.lproj/Main.strings have been converted to mul.lproj/Main.xcstrings

I used it and everything worked perfectly:

  1. the translations are in a separate file;
  2. they load without problems.

enter image description here

Glyceric answered 27/7 at 9:34 Comment(0)
H
-1

XIB files do not have their own ".strings" files. You can generate ".strings" from XIB using ibtool, then after translation you use ibtool again to embed the translations into the localized XIB.

If you still have only one English XIB, you need to create a French XIB using Xcode, then do the ibtool process.

Take a look here: https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/Articles/LocalizingInterfaces.html

Helmsman answered 17/10, 2013 at 12:52 Comment(2)
When I used base internationalization I specified for French language all my XIB files. xCode create for each XIB file a file .string corresponding. So I don't have to use ibtool ?Parenteral
You're right, I forgot about Base Internationalization. Note that this feature only works when building for iOS 6.0 or greater (iOS deployment target). What is your iOS deployment target?Helmsman

© 2022 - 2024 — McMap. All rights reserved.