对于iOS开发者来说 自动布局对于一个可以横屏竖屏的项目来说至关重要。当然你可以设置两次的frame ,但是对于以后,自动布局会越来越普遍。而masonry这个自动布局的框架是很好用的。下面,是我在网上自学的masonry布局。加了自己的一些理解。本人菜鸟,第一次写博客,那些的不好,不对的地方求大神指出来。谢谢大家了。
//
// ViewController.m
// test
//
// Created by fantasy on 15/10/16.
// Copyright © 2015年 fantasy. All rights reserved.
//
#import "ViewController.h"
#import "Masonry.h"
#define myWidth [UIScreen mainScreen].bounds.size.width
#define myHeight [UIScreen mainScreen].bounds.size.height
//避免代码块的循环引用
#define WS(weakSelf) __weak __typeof(self)weakSelf = self
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self demoTest4];
}
//1. 居中显示一个view 固定宽度和高度
- (void)demoTest1{
WS(weakSelf);
UIView *view1 =[[UIView alloc]init];
view1.backgroundColor = [UIColor yellowColor];
/*
mas_remakeConstraints
针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况
mas_makeConstraints
只负责新增约束 Autolayout不能同时存在两条针对于同一对象的约束 否则会报错
mas_updateConstraints
则会清除之前的所有约束 仅保留最新的约束
三种函数依情况而定
*/
//无需设置frame了
// view1.frame=CGRectMake(100, 100, 100, 100);
//必须加到父控件上去
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
//使view1的居中显示
make.center.equalTo(weakSelf.view);
//固定view1的宽度和高度
make.size.mas_equalTo(CGSizeMake(200, 200));
}];
//在这打印view1的frame 你看看有什么发现
NSLog(@"view1.frame %@",NSStringFromCGRect(view1.frame));
}
//2.让一个view略小于其父控件
-(void)demoTest2{
WS(weakSelf);
//设置一个view1
UIView *view1 =[[UIView alloc]init];
view1.backgroundColor = [UIColor yellowColor];
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(weakSelf.view);
make.size.mas_equalTo(CGSizeMake(300, 200));
}];
//添加view1的子控件
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor blueColor];
[view1 addSubview:view2];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
//第一种约束方式
make.top.equalTo(view1).with.offset(10);
make.left.equalTo(view1).with.offset(10);
make.bottom.equalTo(view1).with.offset(-10);
make.right.equalTo(view1).with.offset(-10);
//其中bottom和right是负数
//百度上说 那么为什么bottom和right里的offset是负数呢? 因为这里计算的是绝对的数值 计算的bottom需要小于view1的底部高度 所以要-10 同理用于right
//我的理解是bottom是相对view1的bottom来说的 -10的意思就是以view1.bottom准线 -10个点的线上
//第二种约束方式
// make.top.left.bottom.right.equalTo(view1).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
//第三种约束方式
// make.edges.equalTo(view1).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];
}
//3.让两个高度为180的view垂直居中且等宽等间距排列 间距为10(自动计算其宽度)
-(void)demoTest3{
WS(weakSelf);
//设置一个view1
UIView *view1 =[[UIView alloc]init];
view1.backgroundColor = [UIColor yellowColor];
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(weakSelf.view);
make.size.mas_equalTo(CGSizeMake(250, 250));
}];
//两个子控件
CGFloat viewH = 180; //@180
CGFloat marginX = 10;
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor orangeColor];
[view1 addSubview:view2];
UIView *view3 = [[UIView alloc]init];
view3.backgroundColor = [UIColor orangeColor];
[view1 addSubview:view3];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
// make.centerY.mas_equalTo(view1.mas_centerY);
//与下一个句子等价
make.centerY.mas_equalTo(view1);
make.left.equalTo(view1.mas_left).with.offset(marginX);
make.right.equalTo(view3.mas_left).with.offset(-marginX);
// make.height.equalTo(@180);
//与下一个句子等价
make.height.mas_equalTo(viewH);
make.width.equalTo(view3);
}];
[view3 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(view1.mas_centerY);
make.left.equalTo(view2.mas_right).with.offset(marginX);
make.right.equalTo(view1.mas_right).with.offset(-marginX);
make.height.mas_equalTo(viewH);
make.width.mas_equalTo(view2);
}];
}
//4.在UIScrollView顺序排列一些view并自动计算contentSize
-(void)demoTest4{
//创建scrollView
WS(weakSelf);
UIScrollView *scrollView = [[UIScrollView alloc]init];
scrollView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:scrollView];
[scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(weakSelf.view);
make.width.mas_equalTo(myWidth);
make.height.mas_equalTo(@300);
}];
//容器view 只是为了拿到上一个添加在这里面的view
UIView *containerView = [[UIView alloc]init];
containerView.backgroundColor = [UIColor blueColor];
[scrollView addSubview:containerView];
[containerView mas_makeConstraints:^(MASConstraintMaker *make) {
#pragma mark - 这里设置edge 使scrollView.contentSize随着容器高度变化而变化
make.edges.equalTo(scrollView);
make.width.equalTo(scrollView);
}];
//添加子控件
int count = 10;
UIView * lastView = nil;
for (int i = 1; i<=count; i++) {
UIView *subview1 = [[UIView alloc]init];
[containerView addSubview:subview1];
subview1.backgroundColor = [UIColor
colorWithHue:( arc4random() % 256 / 256.0 )
saturation:( arc4random() % 256 / 256.0 ) + 0.5
brightness:( arc4random() % 256 / 256.0 ) + 0.5
alpha:1];
[subview1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.equalTo(containerView);
make.height.mas_equalTo(@(20*i));
if (lastView) {
//相当于i!=1时
make.top.mas_equalTo(lastView.mas_bottom);
// NSLog(@"不为空 lastView %@ i== %d",lastView,i);
}else{//相当于i==1时
make.top.mas_equalTo(containerView.mas_top);
// NSLog(@"为空 lastView %@ i== %d",lastView,i);
}
}];
lastView=subview1;
}
/*
可能是因为容器视图的高度==scrollView.contentSize
在这里对容器视图的高度添加了约束 因为约束了容器视图的edge make.edges.equalTo(scrollView);
所以scrollView.contentSize会变
*/
//最后这一句话 指定了containerView的frame 虽然打印他的frame没结果 同时也指定了scrollView的contentSize
[containerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(lastView.mas_bottom);
}];
}
//5.一些杂的东西 数组了 优先权 设置某一属性的最大值 最小值
-(void)demoTest5{
WS(weakSelf);
UIView *view1 = [[UIView alloc]init];
view1.backgroundColor = [UIColor redColor];
[self.view addSubview:view1];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
// make.center.equalTo(weakSelf.view);
make.center.equalTo(weakSelf.view).centerOffset(CGPointMake(-50, 0));
make.size.mas_equalTo(CGSizeMake(200, 200));
// make.size.equalTo(weakSelf.view).sizeOffset(CGSizeMake(-20, -40));
// make.left.and.top.equalTo(weakSelf.view).with.offset(20);
// make.width.equalTo(@100);
// make.height.equalTo(@200);
// make.height.equalTo(@[@100,@200,@300]);
// make.centerY.equalTo(weakSelf.view.mas_centerY);
//对于数组 好像默认的是最小的那个
// make.left.equalTo(@[@100,@10]);
//优先权 优先约束那个条件
// make.left.equalTo(@10).with.priorityMedium();
// make.left.equalTo(@50).with.priorityLow();
// make.left.equalTo(@100).with.priorityHigh();
//width >= 200 && width <= 300
// make.width.greaterThanOrEqualTo(@200);
// make.width.lessThanOrEqualTo(@300);
// make.height.equalTo(@100);
}];
}
//九宫格布局 想找一个简单的 不用遍历到每一个子控件方法 暂时没找出来
-(void)demoTest6{
WS(weakSelf);
//背景图片
UIView *superView = [[UIView alloc]init];
superView.backgroundColor = [UIColor grayColor];
[self.view addSubview:superView];
[superView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(weakSelf.view);
make.height.equalTo(@200);
make.left.equalTo(weakSelf.view).offset(10);
make.right.equalTo(weakSelf.view).offset(-10);
}];
//九宫布局
int count = 7;
//创建views
for (int i = 0; i < count; i++) {
UIView *suberView = [[UIView alloc]init];
suberView.tag = i;
superView.backgroundColor = [UIColor yellowColor];
[superView addSubview:suberView];
}
CGFloat viewMarginW = 10;
CGFloat viewMarginH = 20;
CGFloat viewWH = 30;
//一行最大的view个数
int maxCountHang = 3;
//对views添加约束
for (UIView *view1 in superView.subviews) {
//1 2 3 4 5
int hang = (int)view1.tag / maxCountHang + 1;
//1 2 3
int lie =(int)view1.tag % maxCountHang + 1;
if (view1.tag==0) {//第一个
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.and.height.equalTo(@30);
make.top.equalTo(@20);
make.left.equalTo(@10);
}];
}else{//其他
return;
for (UIView * view2 in superView.subviews) {
//view2就是上一个view
if (view2.tag == view1.tag-1) {
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.and.height.mas_equalTo(viewWH);
if (lie>1) {
make.left.mas_equalTo(view2).offset(viewMarginW);
}else{
make.left.mas_equalTo(viewMarginW);
}
if (hang>1) {
make.top.mas_equalTo(view2).offset(viewMarginH);
}else{
make.top.mas_equalTo(viewMarginH);
}
}];
}
}
}
}
// int hang = i / maxCountHang + 1;
// int lie = i % maxCountHang + 1;
}
@end