RTL Considerations
October 19, 2020 -Here are some things to keep in mind so that you app can handle right-to-left languages like Arabic and Hebrew.
Guidelines
While Apple provides information about supporting RTL (right to left), I generally refer to Mozilla's RTL Guidelines and Google's for information about what should flip for RTL and what should not.
RTL Images
Mirroring images which are packaged with the app are handled automatically by the system. All we need to do is mark the images in the asset catalog as left-to-right versions and the system will take care of flipping them for RTL.
The default value for Direction is Fixed
which is perfect for images that do not need to be flipped such as smiley-faces and images of clocks. Select Left to Right
for images such as navigation arrows which should flip in RTL.
Trailing Constraints
Views generally need trailing constraints specified in Autolayout and not only leading constraints. By specifying trailing constraints even when they’re seemingly not necessary, you can make sure that in RTL mode, elements will layout in a nice way.
textContentType
Text fields should have their textContentType
set according to the content you expect in the field. This will help iOS to flip the proper fields as well as offer better auto-complete suggestions. Phone numbers, for example, should not be flipped in RTL.
UICollectionView Layouts
Horizontally-scrolling collection view layouts usually will need to be able to scroll in the opposite direction. This can be handled automatically by adding one override to your layout subclass:
override var flipsHorizontallyInOppositeLayoutDirection: Bool {
return true
}
If you do not allow the layout to flip, the page indicator below likely will. If you mean for the collection view not to flip, you'll need to prevent the page indicator from flipping to match to avoid confusion.
Directional Insets
Where possible, use NSDirectionalEdgeInsets
instead of UIEdgeInsets
. If you are supporting a version of iOS so old you cannot use this (directional insets were added in iOS 11), you'll need to write your own convenience function to flip your right and left insets based on the component's effectiveUserInterfaceLayoutDirection
.
Un-mirrored UI Elements
Some elements, such as phone numbers, should not be mirrored. When creating UI elements like this, remember to use right and left anchors explicitly in Autolayout. This includes in views where the element is used. Consider the margins and constraints used to position the element on the screen, if they are based on neighboring leading or trailing anchors, the element will not position correctly in its parent-view.
Text Alignment
For labels and such which should flip for RTL languages, using textAlignment = .left
will not display like you'd expect. You can instead chose .natural
which will align text to the left for LTR languages and to the right for RTL languages. This is the default for UILabels, so in most case you won't need to write code to change it at all.
Manual Frame Math
Sometimes, for performance reasons for example, you may want to avoid using Autolayout altogether and instead use frames to position elements manually. In this case, it's important to factor in the current value of the UIView
property effectiveUserInterfaceLayoutDirection
. A function like this could be used to adjust their frame math based on direction:
func directionAdjustedFrame(leading: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) -> CGRect {
if effectiveUserInterfaceLayoutDirection == .leftToRight {
return CGRect(
x: leading,
y: y,
width: width,
height: height
)
} else {
return CGRect(
x: bounds.width - width - leading,
y: y,
width: width,
height: height
)
}
}
Language-Based Detection
For some content, such as chat conversations, you may want the text alignment to match the language of the content instead of the alignment the system would chose to match the system language. In this case, you can use functions like CFStringTokenizerCopyBestStringLanguage
to attempt to detect the language of the content to decide alignment. This is not 100% accurate, but they can offer a good-enough solution without dramatically impacting performance.