Search code examples
ioscocoa-touchlocalizationautolayoutright-to-left

Autolayout Percentage-based Placement in Right-to-left Language


I am having issues placing a subview in my view that is a percentage distance from the trailing edge. It works fine in regular left-to-right languages (such as English), but when I localize into a right-to-left language (such as Arabic or Hebrew), the constraint seems to zero out and butt directly against the trailing edge (left side in this case). I created a minimal test project and have been able to reproduce the issue there.

All of my views are set up in xib files, not in storyboard.

I created a ViewController with a xib. I then put in a fixed-size 50x50 subview and placed it a fixed 100 from the top and then the trailing edge 80% to the superview's trailing, as seen in this screen shot:

Autolayout Setup

Just for good measure, and to ensure that it's flipping the view, I added in a label that is completely independent of the other subview. When I run this in English, everything looks great:

LTR Correct Layout

However, upon changing the device's language to Arabic, the label mirrors correctly but it seems to forget the percentage of the trailing constraint and just sees the constant of 0, which causes the subview to be placed directly on the side of the view.

RTL Bad Layout

Does anyone know how I need to modify my constraints in order for the device to remember the percentage-based constraint to the trailing edge in an RTL language?


Solution

  • Found the issue- it turns out the issue is that when the autolayout constraints flip direction, the coordinate system does not. This means that the standard LTR constraint is placing the trailing edge at 80% of the right edge's coordinate value (which is equal to the view's width). However, when the view constraint is flipped for the RTL language, it is now 80% of the left edge's coordinate value, which is now 0.

    Unfortunately, there doesn't appear to be an easy solution to this. I tried placing the view at a percentage relative to the center of the view instead. Again, it works fine in LTR but when switching to RTL it maintains the exact same location on the right side of the view (so it does not mirror properly). TBH, I'm not sure how any percentage-based constraints work in both LTR and RTL that aren't centered.

    The solution for now is to set the constraint at runtime based on the appropriate paradigm. So in LTR I set it at about 150% of the center coordinate, but if it's RTL I go about 50%.