服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
当前位置: 主页 > 开发教程 > ios开发教程 >

UIScrollView利用Masonry框架来自动布局

时间:2016-06-15 22:57来源:未知 作者:好模板 点击:
本文主要是针对UIScrollView利用Masonry框架来自动布局,因为UIScrollView可以滑动,所以本身布局跟一般的UIView不太一样,然后楼主之前面试的时候也有人问过楼主这个问题,所以楼主想简单

本文主要是针对UIScrollView利用Masonry框架来自动布局,因为UIScrollView可以滑动,所以本身布局跟一般的UIView不太一样,然后楼主之前面试的时候也有人问过楼主这个问题,所以楼主想简单总结一下方便你我他它。关于Masonry这个框架,相信大家也都在用它,可以去github上面下载,它里面的各种demo也是非常有用的。

我们设置约束用到的几个方法简单介绍:

一.mas_makeConstraints:设置约束,如果你的视图不需要根据什么情况更新约束,只需要设置一次的话,请使用它。

错误示范:多次调用

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.scrollView];
    [self.scrollView addSubview:self.containerView];
    [self.containerView addSubview:self.testButton];
    [self.containerView addSubview:self.testView]; 
    // 设置约束
    [self setupConstraints];
}

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

    [self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.edges.equalTo(self.scrollView);
         make.width.equalTo(self.scrollView);
    }];

    [self.testButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.containerView).offset(100);
        make.left.equalTo(self.containerView).offset(50);
        make.right.equalTo(self.containerView).offset(-50);
        make.height.equalTo(@40);
    }];

    [self.testView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.testButton.mas_bottom).offset(200);
        make.left.right.equalTo(self.containerView);
        make.height.equalTo(@400);
        make.bottom.equalTo(self.containerView);
    }];
}

- (void)testButtonClick {
    [self setupConstraints];
}

结果:

第一次添加约束时,约束数组是酱紫的:


1.png


这时候约束数组的count为0,是正确的,因为我们之前没有设置过约束,点击测试按钮,再添加一次约束,结果是酱紫的:


2..png


这时候,约束数组的count值是4,也是正确的,因为我们添加过一次了,可是这次点击过后,约束数组的count就会变成8了:


3.png

很明显,点击一次就会重复累加而不会清除之前的约束,后果可想而知。。。说到这里,大家应该理解mas_makeConstraints的使用场景了。

二.mas_updateConstraints:更新约束,如果你的布局需要根据具体情况来更新子控件的约束,那么请使用它。mas_updateConstraints是对比该对象之前的约束数组,添加过的约束就直接修改它的值,没有添加过的约束就添加上。


4.png


结论:无论你点多少次都不重复添加约束,感觉mas_updateConstraints真是棒棒哒。

三.mas_remakeConstraints:在mas_makeConstraints的基础上会清除掉之前所有的约束,再重新添加新的约束。

UIScrollView的自动布局问题

在利用自动布局来布局UIScrollView时,一般都会在上面添加一个UIView的子控件,来正确布局:

代码片段

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.scrollView];
    [self.scrollView addSubview:self.containerView];
    [self.containerView addSubview:self.testButton];
    [self.containerView addSubview:self.testView];

    [self.view setNeedsUpdateConstraints];
}

- (void)updateViewConstraints {
    [self.scrollView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(64);
        make.left.right.bottom.equalTo(self.view);
    }];

    [self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
         make.edges.equalTo(self.scrollView);
        // 确定containerView的宽度
         make.width.equalTo(self.scrollView);
    }];

    [self.testButton mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.containerView).offset(100);
        make.left.equalTo(self.containerView).offset(50);
        make.right.equalTo(self.containerView).offset(-50);
        make.height.equalTo(@40);
    }];

    [self.testView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.testButton.mas_bottom).offset(200);
        make.left.right.equalTo(self.containerView);
        make.height.equalTo(@400);
        // 确定containerView的高度
        make.bottom.equalTo(self.containerView);
    }];

  // 必须要调用
    [super updateViewConstraints];
}

scrollView的contentSize要根据containerView的高度来设置,containView的高度又要根据它内部的子控件来设置,make.bottom.equalTo(self.containerView)确定containerView的高度,make.width.equalTo(self.scrollView)确定containerview的宽度。

模拟复杂环境下UISCrollView的自动布局

现假如有这么一种需求:一个控制器里面有多个视图A B C D,而每个视图的内容要去请求网络获取数据才能确定高度,但是对于这几个网络请求谁先成功获取数据计算到高度是不确定的,如何布局?

代码片段

#pragma mark -- life cycle
- (void)viewDidLoad {
    [super viewDidLoad];

    self.oneHeight = 0;
    self.twoHeight = 0;
    self.threeHeight = 0;
    self.fourHeight = 0;

    [self.view addSubview:self.scrollView];
    [self.scrollView addSubview:self.containerView];

    [self.containerView addSubview:self.oneLabel];
    [self.containerView addSubview:self.twoLabel];
    [self.containerView addSubview:self.threeLabel];
    [self.containerView addSubview:self.fourLabel];

    [self.view setNeedsUpdateConstraints];

    // 模拟3s后网络请求数据回来了,oneLabel根据数据获得了高度。
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.oneHeight = 80;
        [self.view setNeedsUpdateConstraints];
    });

    // 模拟6s后网络请求数据回来了,fourLabel根据数据获得了高度。
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.fourHeight = 100;
        [self.view setNeedsUpdateConstraints];
    });

    // 模拟9s后网络请求数据回来了,twoLabel根据数据获得了高度。
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(9 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.twoHeight = 150;
        [self.view setNeedsUpdateConstraints];
    });

    // 模拟12s后网络请求数据回来了,threeLabel根据数据获得了高度。
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(12 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.threeHeight = 60;
        [self.view setNeedsUpdateConstraints];
    });


}

- (void)updateViewConstraints {
    [self.scrollView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];

    [self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.scrollView);
        make.width.equalTo(self.scrollView);
    }];

    [self.oneLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.containerView).offset(50);
        make.left.right.equalTo(self.containerView);
        make.height.equalTo(@(self.oneHeight));
    }];

    [self.twoLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.oneLabel.mas_bottom);
        make.left.right.equalTo(self.containerView);
        make.height.equalTo(@(self.twoHeight));
    }];

    [self.threeLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.twoLabel.mas_bottom);
        make.left.right.equalTo(self.containerView);
        make.height.equalTo(@(self.threeHeight));
    }];

    [self.fourLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.threeLabel.mas_bottom);
        make.left.right.equalTo(self.containerView);
        make.height.equalTo(@(self.fourHeight));
        make.bottom.equalTo(self.containerView);
    }];

    [super updateViewConstraints];
}

结果:楼主做的这个gif图跟实际有点差别,将就看


(责任编辑:好模板)
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容