使用Masonry,对scrollView进行布局的问题

sparkly
  • 10

今天在做项目的时候,遇到一个bug,一开始怎么都找不到问题所在。又重写了一个demo,发现了问题出现的原因。
先来描述一下出现的bug。现在有一个Scrollview,所做设置如下:

self.scrollView = [[UIScrollView alloc] init];
    self.scrollView.backgroundColor = [UIColor lightGrayColor];
    self.scrollView.delegate = self;
    self.scrollView.pagingEnabled = YES;
    [self.view addSubview:_scrollView];
    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.bottom.right.equalTo(self.view);
    }];

然后有一个containerView,将他作为scrollview的唯一子视图:

self.container = [[UIView alloc] init];
    self.container.backgroundColor = [UIColor yellowColor];
    [self.scrollView addSubview:_container];
    [self.container mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.scrollView);
        make.height.equalTo(self.scrollView);
    }];

下面是两个子视图:

//为了省事,名字求轻喷。
    Base1View *view1 = [[Base1ViewController alloc] init];
    view1.backgroundColor = [UIColor purpleColor];
    [self.container addSubview:view1];
    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.bottom.equalTo(_container);
         make.width.equalTo(self.view.mas_width);
    }];
    
    Base2View *view2 = [[Base2ViewController alloc] init];
    view2.backgroundColor = [UIColor orangeColor];
    [self.container addSubview:view2];
    [view2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(view1.mas_right);
        make.top.bottom.equalTo(_container);
        make.width.equalTo(self.view.mas_width);
    }];

添加container的右边约束

 [self.container mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(view2.mas_right);
    }];

以上是所有代码。运行效果如下:
第一屏

第一个页面翻转过后都正常。
但是第二个页面就出现了问题:
横屏

竖屏
从图中可以看出来,scrollView的偏移量发生了改变。
我感觉是这里出了问题:

    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.top.bottom.equalTo(_container);
        make.width.equalTo(self.view.mas_width);//这里我尝试把width设置为固定(375);
    }];

然后把View2的改为:

    [view2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(view1.mas_right);
        make.top.bottom.equalTo(_container);
//        make.width.equalTo(self.view.mas_width);
        make.right.equalTo(self.view).offset(375);
    }];

可以得到解决,但是这不是一个科学的方法,又找不到合适的方法,特来此请教大家。

回复
阅读 12.4k
1 个回答

scrollView使用自动约束是要特别小心,使用自动约束之后,scrollView.contentSize会根据它的subviews来进行计算,所以一定要保证添加到scrollView里的subview的宽高是可以确定的值,并且要和scrollView的edge进行正确的约束。建议你去掉container看看

[self.view addSubview:self.scrollView];
[self.scrollView addSubview:view1];
[self.scrollView addSubview:view2];

[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.left.bottom.right.equalTo(self.view);
}];

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.top.bottom.equalTo(self.scrollView);
    make.width.equalTo(self.view.mas_width);
    make.height.equalTo(self.view.mas_height);
}];

[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(view1.mas_right);
    make.top.and.bottom.and.right.equalTo(self.scrollView);
    make.width.equalTo(self.view.mas_width);
    make.height.equalTo(self.view.mas_height);
}];
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏