Ben Dodson

Freelance iOS, Apple Watch, and Apple TV Developer

Forcing left-to-right text in iOS localizations

Since iOS 6 it has been the case that any localization that utilises a right-to-left language (such as Arabic) will automatically flip your views so that everything scans from right-to-left. Usually this is desireable but there are certain instances where you may want to disable this functionality (such as with a media player that should scrub from left-to-right). I was recently asked by a client to completely disable the right-to-left functionality for all languages as it was causing too many display issues within the app and customers were specifically saying they’d prefer it to scan that way.

After a bit of searching, the general consensus was that I’d need to manually alter1 all of my horizontal constraints in order to force them to be left to right rather than leading to trailing which will flip based on localization. In a project with 1000s of these constraints this did not seem a suitable course of action and would require any future developers on the project to keep this in mind when creating new constraints.

Instead, I came across a property added to UIView in iOS 9 named semanticContentAttribute. This allows you to choose unspecified (the default which flips based on localization), playback and spatial which are special cases for media controls or directional controls, and forceLeftToRight and forceRightToLeft which work as their names would suggest. Thanks to the UIAppearance protocol, disabling the flipping globally is a simple one-liner:

UIView.appearance().semanticContentAttribute = .forceLeftToRight

This not only flips all content back to left-to-right but also ensures that your UINavigationController will animate from left-to-right as well. Of course, you can also use the appearanceWhenContainedIn: method to limit this global change to specific view controllers of your app should you wish to or to set certain controls to other directions.

The only other thing I needed to change in my project to get this all working was some paragraph styles for attributed strings. I frequently use NSMutableParagraphStyle to set custom line heights and I leave the other properties to their defaults. One of these is alignment which is always left on my devices due to my English language but the default is actually natural which means it renders depending on the language. Searching through my project and finding the few places I’d left out a default and setting it was fairly trivial:

let paragraph = NSMutableParagraphStyle()
paragraph.lineSpacing = 4.0
paragraph.alignment = .left

In total, I only needed to make 8 edits to my project; much easier than trying to edit every horizontal constraint in your storyboard!

  1. If I had gone down that route I likely would have written a build script that would go through every xib and storyboard file and do this for me but I have been burned by manually editing xib files in the past. That’s a young man’s game! ↩︎

« MPMediaItem+CanAddToLibrary.swift