代码之家  ›  专栏  ›  技术社区  ›  Eitan

带有约束和RTL的UIScrollView的奇怪行为

  •  5
  • Eitan  · 技术社区  · 11 年前

    我有一个水平滚动视图,可以动态添加视图。 在LTR语言上,一切都很好,我从左到右依次添加视图。 在RTL上,问题是视图总是添加到滚动的左侧,而不是像其他控制器一样添加到右侧 真正地 奇怪的是,视图的顺序被正确地添加到第一个视图的左侧,因此它们从右到左排序,但在-x上的滚动视图之外。

    以下是我添加新视图时的代码:

    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;
    
    }
    

    下面是一个图像,说明它如何在LTR和RTL上工作,以及它实际工作的方式 enter image description here

    4 回复  |  直到 11 年前
        1
  •  3
  •   Manuel    7 年前

    这种行为的原因是 UIScrollView 是你忘了把 trailingAnchor 最后一个元素(#4)到滚动视图的 牵引锚 .

    这个 leadingAnchor 滚动视图和元素#1的两个元素彼此连接(见下面的绿色部分)。然而,滚动视图的内容矩形自然地从原点跨越到正坐标方向 (0,0) 向右,向下 (+x, +y) 。在您的情况下,滚动视图的内容大小为宽度 0 因为滚动视图的 引导锚 牵引锚 .

    enter image description here

    所以低于你的 [_scroller addConstraints:_constraint]; 添加类似(伪代码)的内容:

    if tag == lastTag {
      NSLAyoutconstraints.activate([
        tag.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
      ])
    }
    
        2
  •  2
  •   ReedD    11 年前

    听起来更好的方法可能是使用 UICollectionView 。然后,如果你想从右侧开始,你可以这样做:

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

    这样 UICollectionViewFlowLayout 可以为您处理放置。

        3
  •  1
  •   Charan Giri    11 年前

    试试这个

    #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
    

    希望这对你有帮助

        4
  •  1
  •   Steven Jiang    11 年前

    这是我的示例代码。

    //
    //  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
    

    希望能对你有所帮助。