Localizable.strings

Our imaginary app will have a label that says “Hello”.

ruby
@label.text = 'Hello'

It’s an insanely popular app, and now that it’s gone viral, we need to support
users in other countries. We’ll start with French and Japanese, because I don’t
have to go look up how to say “Hello” in those languages.

Localizable.strings files

Translate your strings

You may have noticed that I didn’t create a version of Localizable.strings for
English. I’m assuming here that you are going to use verbose strings, but if
you want to use short strings and then translate them into more verbose ones,
you can certainly do so - just add an en.lproj folder and follow the same
principals that we’ll do here.

resources/fr.lproj/Localizable.strings

"Hello" = "Bonjour";

resources/ja.lproj/Localizable.strings

Srsly?

Yup! That’s enough to have internationalized strings.

And images are easy

If you’ve got hello.png / hello@2x.png in your resources/ folder, add these
files to resources/fr.lproj/ and make them “Frenchy”. Using
UIImage.imageNamed(filename) (or using SugarCube: filename.uiimage) will
find these internationalized files. No code change necessary there.

And layouts are… uh, not as easy

Translation is the easy part. Much harder is designing layouts that take into
account the expectations of users in other countries. Classic iOS development
uses multiple .xib files (placed in those .lproj folders). If you’re using
the ib gem, or something similar, you might be able to follow this practice
(I don’t know, because I don’t like .xib files) .

If, instead, you’re using teacup, you’re basically on your own, but the
constraints/autolayout system can help a LOT. For instance, your labels are
going to be all sorts of different widths, and you might want to have some
alignments that are based on that width. Instead of calculating frames in your
viewDidLoad method, consider how you can establish relationships between the
UILabel frame and your other elements.

ruby
style :label, text: 'Hello'._
style :button, title: 'Hello'._,
constraints: [
constrain(:left).equals(:label, :right).plus(4)
constrain(:top).equals(:label, :top)
]
With these constraints, the button will be to the right of the label, no matter
how wide the label is!