12

I currently have a semi-automated way to localize my views. However, today I found an interesting section in IB, which seems to suggest that I can localize my views from within Interface Builder.

So in IB you can define runtime attributes for a selected object in the Identity Inspector. So for my UILabel I can set the text keypath of my label to the String Hello World.

However, when I choose the Type = Localized String and then the name of a key in my Localized.strings I don't get a translated string but rather just the value (hence the key) which I entered in IB.

I don't understand, how this mechanism is supposed to work. I would love to be able to translate my views like this, any ideas?

Community
  • 1
  • 1
Besi
  • 22,579
  • 24
  • 131
  • 223

3 Answers3

7

The purpose of the "Localized String" type is to let you define a runtime attribute value that will participate in the localization process (using base localization). This is handy if for example you define a custom control, include it in the storyboard and want to assign a localizable string to one of its properties. However this only works on Mac OS, not on iOS.

You can easily confirm this doing the following experiment: put a UILabel / NSTextField in your storyboard and set the "text" / "stringValue" property using a user defined runtime attribute. If you use "String" as the type of the attribute and generate the corresponding strings file you won't see it anywhere in the file. In contrast, if you change the type to "Localized String" and generate the strings file you will find an entry like this:

/* Class = "IBUILabel"; wij-Kq-q92.ibExternalUserDefinedRuntimeAttributesLocalizableStrings[0] = "Localized value"; ObjectID = "wij-Kq-q92"; */
"wij-Kq-q92.ibExternalUserDefinedRuntimeAttributesLocalizableStrings[0]" = "Localized value";

Then you can localize this value in the corresponding language strings file. Again, this works on Mac OS, but not on iOS.

José González
  • 1,207
  • 12
  • 25
  • does this continue to work only on Mac OS and not on iOS in 2016? – helloB Apr 06 '16 at 15:38
  • I don't know, I haven't tried it recently. Anyway you can easily check it using the process described in the answer. Let us know if you do it :) – José González Apr 06 '16 at 16:18
  • I was about to check back in say that runtime attributes are a better option here and work with a simple override of setValue forKeyPath, so that's the option I'm going with. this answer got me most of the way there: http://stackoverflow.com/questions/21870950/localized-string-with-interface-builder-user-defined-runtime-attributes – helloB Apr 06 '16 at 16:19
  • Xcode 8 with iOS8 target: Does not work. Also in a tiny test project: Xcode8/iOS10.3 target: does not work (.strings file not read for user defined runtime attributes) – Rainer Schwarze Jun 16 '17 at 08:15
  • as of Xcode 9 with iOS 10 target: Does not work. My solution to the problem, rather than writing any code or utils, is to make my target language as "Interface Builder Storyboard" instead of "Localizable Strings". (I only required to convert the whole source from Traditional Chinese to Simplified Chinese) – John Pang Nov 16 '17 at 10:32
  • Tested with Xcode 9.4.1, iOS 11 and can verify that it does not work. You are able to extract the strings into .strings files but localized strings will never be fetched from the files when instantiating the components. – Kris Gellci Jul 12 '18 at 20:19
5

The "user defined runtime attributes" are poorly documented. What I can remember from some book I read is, that UDRA was first implemented for MacOSX programming, so the Type "Localized String" could be a feature that is not fully supported for now in iOS.

The funny thing is, that he is translating the strings in the storyboard previews (xCode 4.5.1), but later in the compiled iOS app, he is just injecting the key string.

One solution I am thinking about right now, is to make a little helper class, that is checking the title/text strings of views on viewDidLoad for a keyword like "key", e.g. "XYControllerTitleKey", and then make NSLocalizedString-Method on that.

UPDATE: It seems that in the meantime, there is a way to use the UDRAs:

Storyboard/XIB and localization best practice

And a tutorial as a result (link)

Tim Christmann
  • 148
  • 1
  • 9
  • 1
    Downvoted because the answer is not accurate (at least in current version of Xcode): The type "Localized String" means that the runtime attribute will participate in the localization process, in contrast to using a plain "String" type. You can check this if you generate the strings file from the storyboard: if you use "String" the value won't be included in the generated strings file; if you use "Localized String" it will be. – José González Jul 02 '14 at 09:38
  • 1
    As mentioned in my other comment: The tools for the localization process take care of UDRA, however, the iOS runtime doesn't. The value for UDRA is not taken from the .strings file. – Rainer Schwarze Jun 16 '17 at 08:20
1

For me, using iOS 6, if you generate your strings from your base localized storyboard (by having XCode generate them or using the ibtool --generate-strings-file you'll get autogenerated strings that look like this (should go in MainStoryBoard.strings, for example):

/* Class = "IBUITextField"; b4a-O4-bNZ.ibExternalUserDefinedRuntimeAttributesLocalizableStrings[0] = "Event Name"; ObjectID = "b4a-O4-bNZ"; */
"b4a-O4-bNZ.ibExternalUserDefinedRuntimeAttributesLocalizableStrings[0]" = "Event Name";

Unfortunately, it'd be nice to have them identified by the Key Path, but at least you have the location where your user defined strings should be localized.

andrew
  • 1,173
  • 2
  • 18
  • 28