Search code examples
iosuiscrollviewautolayoutright-to-leftnslayoutconstraint

Strange behavior of UIScrollView with Constraints and RTL


I have an horizontal scroll view on which i add views dynamically. On LTR languages everything work fine, i add views one after the other from left to right. On RTL the problem is that the views always added to the left of the scroll instead of to the right like in every other controller, the really strange staff that the order of the views is added correctly, to the left of the first view so they are ordered from right to left but outside of the scroll view on -x.

Here is my code when i add a new View:

Tag* tag = [self.storyboard instantiateViewControllerWithIdentifier:@"tag" ];
[_scroller addSubview:tag.view];
[tags addObject:tag];
Tag* prev = nil
for (Tag* tag in tags)
{
    if (prev == nil)
    {
        [_scroller addConstraint:[NSLayoutConstraint constraintWithItem:tag.view 
                                                       attribute:NSLayoutAttributeLeading                                                                                          
                                                       relatedBy:NSLayoutRelationEqual
                                                                     toItem:_scroller
                                                                  attribute:NSLayoutAttributeLeading
                                                                 multiplier:1.0f
                                                                   constant:0]];
    }
    else
    {
        [_scroller addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[prev]-10-[tag]"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:@{@"tag" : tag.view, @"prev" : prev.view}]];
    }

    [_scroller addConstraint:[NSLayoutConstraint constraintWithItem:tag.view
                                                          attribute:NSLayoutAttributeCenterY
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:_scroller
                                                          attribute:NSLayoutAttributeCenterY
                                                             multiplier:1.0f
                                                               constant:0]];
    prev = tag;

}

Here is an image of how it suppose to work on LTR and RTL and how it actually works enter image description here


Solution

  • It sounds like a better approach might be to use a UICollectionView. Then if you want to start it from the right side you could possibly do something like this:

    NSIndexPath *lastIndex = [NSIndexPath indexPathForItem:data.count - 1 
                                                 inSection:0];
    [self.collectionView scrollToItemAtIndexPath:lastIndex 
                                atScrollPosition:UICollectionViewScrollPositionRight 
                                        animated:NO];
    

    This way the UICollectionViewFlowLayout can handle the placement for you.