{"id":3405,"date":"2013-01-04T18:46:12","date_gmt":"2013-01-04T23:46:12","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=3405"},"modified":"2020-08-18T05:24:42","modified_gmt":"2020-08-18T12:24:42","slug":"howto-localize-ios-storyboards-monotouch","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/howto-localize-ios-storyboards-monotouch\/","title":{"rendered":"Localizing iOS 6 Storyboards with MonoTouch"},"content":{"rendered":"<p>Localization and internationalization of XIB and Storyboard files has historically been a very manual process. Typically, these file types would be duplicated in each &#8216;language directory&#8217; (*.lproj) and then the text and layout would be tweaked independently by each translator. Changes to the actual Storyboard or XIBs would need to be manually propagated across all the &#8216;language copies&#8217;. In iOS6 Apple introduced a new concept &#8211; Base Localization &#8211; which you can read about in their documentation on <a href=\"https:\/\/developer.apple.com\/library\/ios\/#referencelibrary\/GettingStarted\/RoadMapiOS\/chapters\/InternationalizeYourApp\/InternationalizeYourApp\/InternationalizeYourApp.html\" target=\"_blank\" rel=\"noopener noreferrer\">Internationalizing Your App<\/a>. Your project can contain a &#8216;special&#8217; Base.lproj directory where the Storyboard files are located, and then a corresponding *.strings file (whose filename matches the Storyboard&#8217;s) in each language directory with the translations. There is a small sample showing how this works with MonoTouch\u2014<a href=\"https:\/\/github.com\/conceptdev\/xamarin-samples\/tree\/master\/TaskyL10nStoryboard\" target=\"_blank\" rel=\"noopener noreferrer\">TaskyL10nStoryboard on github<\/a>. There is no IDE support currently, but you can easily create the Base.lproj directory manually in MonoDevelop and everything works as expected. Here&#8217;s a screenshot of the project structure:<a href=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/04\/Storyboard-l10n-project-250x300.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/04\/Storyboard-l10n-project-250x300-250x300.png\" alt=\"\" width=\"250\" height=\"300\" class=\"alignnone size-medium wp-image-43220\" \/><\/a> Then, inside the Storyboard itself, you need to identify the controls you wish to localize. Click on a control to discover its <strong>Object ID<\/strong>, as shown in this screenshot: <a href=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/04\/Storyboard-l10n-objectid-300x254.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/04\/Storyboard-l10n-objectid-300x254-300x254.png\" alt=\"\" width=\"300\" height=\"254\" class=\"alignnone size-medium wp-image-43219\" \/><\/a> Using the <strong>Object IDs<\/strong> from the Storyboard file, we can translate the display values for various properties (including text, placeholders, and others) in the MainStoryboard.strings file in each language directory, like this:<\/p>\n<pre class=\"lang:xml decode:true\">\"SXg-TT-IwM.placeholder\" = \"nombre de la tarea\";\n\"Pqa-aa-ury.placeholder\"= \"otra informaci\u00f3n de tarea\";\n\"zwR-D9-hM1.text\" = \"Detalles de la tarea\";\n\"bAM-2j-Rzw.text\" = \"Notas\";\n\"NF3-h8-xmR.text\" = \"Completo\";\n\"MWt-Ya-pMf.normalTitle\" = \"Guardar\";\n\"IGr-pR-05L.normalTitle\" = \"Eliminar\";\n<\/pre>\n<p>Using the<\/p>\n<p><strong>Object ID<\/strong> and property as the localization key is quite different to Apple&#8217;s previous guidance on localization, where the key is typically the base-language&#8217;s actual displayable value. Here&#8217;s the localized Storyboard, in Japanese: <a href=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/04\/L10n-200x300.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/04\/L10n-200x300-200x300.png\" alt=\"\" width=\"200\" height=\"300\" class=\"alignnone size-medium wp-image-42556\" \/><\/a>  <strong>What about layout?<\/strong> Strings can often be very different lengths in different languages. When you used a different Storyboard or XIB for each language then the control sizes could be manually adjusted to fit. When using Base Localization you should use Apple&#8217;s new constraint-based layout to handle these size differences. <strong>What about iOS 5 and earlier?<\/strong> This method only works on iOS 6. To localize text on earlier versions of iOS, you will have to duplicate your Storyboards and XIBs for each language\u2014or create outlets for all the controls and set their localized text values in code using <em>NSBundle.MainBundle.LocalizedString()<\/em>. There is another localized sample\u2014<a href=\"https:\/\/github.com\/conceptdev\/xamarin-samples\/tree\/master\/TaskyL10n\" target=\"_blank\" rel=\"noopener noreferrer\">TaskyL10n<\/a>\u2014which shows how to localize text elements directly and uses <em>MonoTouch.Dialog<\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Localization and internationalization of XIB and Storyboard files has historically been a very manual process. Typically, these file types would be duplicated in each &#8216;language directory&#8217; (*.lproj) and then the text and layout would be tweaked independently by each translator. Changes to the actual Storyboard or XIBs would need to be manually propagated across all [&hellip;]<\/p>\n","protected":false},"author":570,"featured_media":39167,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6,4],"class_list":["post-3405","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Localization and internationalization of XIB and Storyboard files has historically been a very manual process. Typically, these file types would be duplicated in each &#8216;language directory&#8217; (*.lproj) and then the text and layout would be tweaked independently by each translator. Changes to the actual Storyboard or XIBs would need to be manually propagated across all [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/3405","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/570"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=3405"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/3405\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=3405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=3405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=3405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}