Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 445
Eitan Avatar asked Mar 10 '14 07:03

Eitan


1 Answers

The reason for this behavior of UIScrollView is that you forgot to attach the trailingAnchor of the last element (#4) to the scroll view's trailingAnchor.

The leadingAnchor of both the scroll view and element #1 are attached to each other (see below in green). The scroll view's content rect however naturally spans into the positive coordinate directions, from origin (0,0) to right, down (+x, +y). In your case the scroll view's content size is of width 0 because nothing is between scroll view's leadingAnchor and trailingAnchor.

enter image description here

So below your [_scroller addConstraints:_constraint]; add something like (pseudo code):

if tag == lastTag {
  NSLAyoutconstraints.activate([
    tag.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
  ])
}
like image 87
Manuel Avatar answered Sep 22 '22 16:09

Manuel