Question

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

Was it helpful?

Solution 2

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.

OTHER TIPS

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)
  ])
}

Try this

#import "ViewController.h"

@interface ViewController ()<UIScrollViewDelegate>
{
UIView *baseView;
UILabel *titleLabel;
NSMutableArray *infoArray ;
UIScrollView *mainscrollview;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];

infoArray =[[NSMutableArray alloc]initWithObjects:@"1",@"2",@"3", nil];
   NSLog(@"%@",infoArray);
mainscrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 380)];
mainscrollview.delegate=self;
mainscrollview.contentSize=CGSizeMake(320*infoArray.count, 0);
[self.view addSubview:mainscrollview];
[self sscrollcontent:@"LTR"];//LTR for Lefttoright other than LTR it will show RTL
}
-(void)sscrollcontent:(NSString *)flowtype
{
int xaxis=0;
for (int i=0; i<infoArray.count; i++) {
    baseView=[[UIView alloc]initWithFrame:CGRectMake(xaxis, 0, 320, 380)];
    [mainscrollview addSubview:baseView];
    titleLabel =[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 60)];
    titleLabel.textAlignment=NSTextAlignmentCenter;
    if ([flowtype isEqualToString:@"LTR"]) {
        titleLabel.text=infoArray[i];

    }
    else
    {
        titleLabel.text=infoArray[infoArray.count-i-1];

    }
    [baseView addSubview:titleLabel];
    xaxis=xaxis+320;
}
}

@end

Hope this will help you

This is my sample code.

//
//  ViewController.m
//  testConstraint
//
//  Created by stevenj on 2014. 3. 24..
//  Copyright (c) 2014년 Steven Jiang. All rights reserved.
//

#import "ViewController.h"


@interface TagView : UILabel
- (void)setNumber:(NSInteger)num;
@end

@implementation TagView

- (void)setNumber:(NSInteger)num
{
    [self setText:[NSString stringWithFormat:@"%d",num]];
}

@end

@interface ViewController ()

@property (nonatomic, strong) UIScrollView *scroller;
@property (nonatomic, strong) NSMutableArray *tags;
@property (nonatomic, strong) NSMutableArray *constraint;

@end

@implementation ViewController

@synthesize scroller = _scroller;

- (void)viewDidLoad
{
    [super viewDidLoad];
    _tags = [NSMutableArray new];
    _constraint = [NSMutableArray new];
    // Do any additional setup after loading the view, typically from a nib.

    //step.1 create scroll view
    _scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 20, 320, 60)];
    [_scroller setBackgroundColor:[UIColor lightGrayColor]];
    [_scroller removeConstraints:[_scroller constraints]];
    [_scroller setTranslatesAutoresizingMaskIntoConstraints:YES];

    [self.view addSubview:_scroller];


    //step.2 add tag view
    for (int i=0; i<10; i++) {
        TagView *tag = [[TagView alloc] init];

        [tag setFrame:CGRectMake(100, 30, 50, 30)];
        [tag setNumber:i];

        [tag.layer setBorderWidth:1.0];
        [tag setTranslatesAutoresizingMaskIntoConstraints:NO];

        [_scroller addSubview:tag];
        [_tags addObject:tag];
    }

    //step.3 update contraints
    [self myUpdateConstraints];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)myUpdateConstraints
{
    [_constraint removeAllObjects];

    TagView* prev = nil;
    for (TagView* tag in _tags)
    {
        [tag setNumber:[_tags indexOfObject:tag]];

        if (prev == nil)
        {

            [_constraint addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(<=300)-[tag]-20-|"
                                                                                     options:NSLayoutFormatDirectionLeadingToTrailing
                                                                                     metrics:nil
                                                                                       views:@{@"tag" : tag}]];
        }
        else
        {
            [_constraint addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"[tag]-10-[prev]"
                                                                              options:0
                                                                              metrics:nil
                                                                                views:@{@"tag" : tag, @"prev" : prev}]];

        }

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

        prev = tag;

    }
    [_scroller addConstraints:_constraint];
}
@end

Hopes it could help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top