自动布局

自动布局

1 什么是自动布局?

UI 根据不同尺寸的屏幕动态的布局控件大小.

2 作用

适配所有机型

3 布局中常用的参数

  • autoResizing就是一个相对于父控件的布局解决方法;由于它只能相对父控件布局;因此不能约束子控件之间关系. 所以出现了aotolayout,既可以设置父子控件之间的关系也可以设置同级控件之间的关系
  • 注: 在用autoResizing的时候需要关闭autoLayout和sizeclass,因为他们之间是互相冲突的.
  • Autolayout的作用非常明确:帮我们确定在不同设备、不同(父view)环境下,同一个可视单元所应具有合适的位置和尺寸,因此,当一个 UIView上所施加的约束能够唯一确定它的frame(x, y, width, height)的时候我们的自动布局的使用才是正确的
  • sizeClass: 对屏幕尺寸进行了抽象.

4 Autolayout的两条核心概念:

  >1 参照:通过参照其他控件或父控件来设置当前控件地位置和大小

  >2 约束Constraints(规则):通过添加约束限制控件地位置和大小

5 代码实现Autolayout的步骤:

 5.1 利用NSLayoutConstraint类创建具体的约束对象

 5.2 添加约束对象到相应的view上

- (void)addConstraint:(NSLayoutConstraint *)constraint;

- (void)addConstraints:(NSArray *)constraints;

5.3 代码实现Autolayout的注意点:


> 要先禁止autoresizing功能,设置view的下面属性为NO

view.translatesAutoresizingMaskIntoConstraints = NO;

> 添加约束之前,一定要保证相关控件都已经在各自的父控件上

> 不用再给view设置frame

> 自动布局有个核心公式:

 obj1.property1 =(obj2.property2 * multiplier)+ constant value

6 自动布局的三种方法及优缺点

  • 纯代码

优点: 纯代码实现UI具有最好的代码重用性,也利用版本管理、代码追踪和代码的合并,大型项目大规模的使用。

缺点:纯代码实现存在的问题是开发周期长,代码的维护复杂以及自动布局AutoLayout困难

  • storyboard

优点: StoryBoard实现的优点主要凸显在开发周期短,代码量少,可以明确看到每个ViewController的布局样式和各个控制器之间的跳转关系。

缺点:当然它的弊端也显而易见,不合适多人协作开发,ViewController的重用和自定义view的实现.

  • XIB

优点: Xib的优势在于开发周期快而且版本的维护和纯代码差异性不大,易于维护。

缺点:它的劣势往往体现在Xib的设置往往不是最终的设置,终究会被纯代码所替代。Xib的使用注意点:尽量将xib的工作和代码的工作隔离开来:能够使用xib完成的内容就统一使用xib来做.

7 自动布局的实现

自动布局经过的三个时期

MagicNumber -> autoresizingMask -> autolayout

> 在iphone1-iphone3gs时代 window的size固定为(320,480) 我们只需要简单计算一下相对位置就好了

> 在iphone4-iphone4s时代苹果推出了retina屏 但是window的size不变

>在iphone5-iphone5s时代 window的size变了(320,568) 这时autoresizingMask 

> autoLayout自动布局是iOS6.0之后推出的,在6.0之前多使用autoresizingMasks属性,这个枚举类型的属性都是flexible(伸缩),在有了autoLayout之后这个就很少用了,可以不做了解。

StoryBoard和Xib设置约束在这里也不做具体的介绍,主要介绍三种手写代码设置约束的方法。

1、使用系统的NSLayoutConstraint实现

obj1.property1 =(obj2.property2 * multiplier)+ constant value

 multiplier和constant 就是向量系数和偏移量

1) 一个一个设置约束

-(void)addConstraint:(NSLayoutConstraint *)constraint;

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:30]];

2) 一组一组设置约束

 - (void)addConstraints:(NSArray *)constraints;

[self.view addConstraints:@[

                                //上

                                [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:30],

                                //左

                                [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:10],

                                //下

                                [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-170],

                                //宽

                                [NSLayoutConstraint constraintWithItem:_testView1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.45 constant:0]]];

2) Visual Format Language,翻译过来是“可视化格式语言”  是苹果公司为了简化Autolayout的编码而推出的抽象语言  相当于打出象形文字似得,而且要全在字符串里写,遇到错误比较难调,但是相对来说代码精简了不少.

VFL的详细语法 可以在官方文档中 搜“Visual Format” 就能搜到

 上面的方法中传到的两个参数metrics 和 views 是两个字典。

第一个字典metrics是用来告诉系统里面的每一个值对应哪个字母

第二个字典views是 用来告诉里面的每一个控件对应字符串里的什么

如果整个VFL语言里的所有控件你都是用原名写在里面的,那可以用宏代替

 注释:

 |: 表示父视图

 -:表示距离

 V:  :表示垂直

 H:  :表示水平

 >= :表示视图间距、宽度和高度必须大于或等于某个值

 <= :表示视图间距、宽度和高度必须小宇或等于某个值

 == :表示视图间距、宽度或者高度必须等于某个值

 @  :>=、<=、==  限制   最大为  1000 

 1.|-[view]-|:  视图处在父视图的左右边缘内

 2.|-[view]  :   视图处在父视图的左边缘

 3.|[view]   :   视图和父视图左边对齐

 4.-[view]-  :  设置视图的宽度高度

 5.|-30.0-[view]-30.0-|:  表示离父视图 左右间距  30

 6.[view(200.0)] : 表示视图宽度为 200.0

 7.|-[view(view1)]-[view1]-| :表示视图宽度一样,并且在父视图左右边缘内

 8. V:|-[view(50.0)] : 视图高度为  50

 9: V:|-(==padding)-[imageView]->=0-[button]-(==padding)-| : 表示离父视图的距离

这两个视图间距必须大于或等于0并且距离底部父视图为padding。

 10:  [wideView(>=60@700)]  :视图的宽度为至少为60 不能超过  700

 11: 如果没有声明方向默认为  水平  H:

- (void)setConstraintsByVFL {

    NSDictionary *views = NSDictionaryOfVariableBindings(self.view,_testView1,_testView2,_testView3);

   

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[_testView1(==_testView2)]-10-[_testView2]-10-|" options:0 metrics:0 views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_testView1(<=700)]-10-[_testView3]-10-|" options:0 metrics:0 views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_testView2(<=700)]-10-[_testView3]-10-|" options:0 metrics:0 views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_testView3]-10-|" options:0 metrics:0 views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_testView3(==150)]-10-|" options:0 metrics:0 views:views]];

}

2.Masonry的使用

mas_makeConstraints 是给view添加约束,约束有几种,分别是边距,宽,高,左上右下距离,基准线。添加过约束后可以有修正,修正有offset(位移)修正和multipliedBy(倍率)修正。

语法一般是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍数和位移修正。

注意点1: 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如[self.view addSubview:view];

注意点2: masequalTo 和 equalTo 区别:masequalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是 通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo,例如 make.left.and.right.equalTo(self.view);

注意点3: 注意到方法with和and,这连个方法其实没有做任何操作,方法只是返回对象本身,这这个方法的左右完全是为了方法写的时候的可读性 。make.left.and.right.equalTo(self.view);和make.left.right.equalTo(self.view);是完全一样的,但是明显的加了and方法的语句可读性更好点。

// exp1: 中心点与self.view相同,宽度为400*400

-(void)exp1{

    UIView *view = [UIView new];

    [view setBackgroundColor:[UIColor redColor]];

    [self.view addSubview:view];

    [view mas_makeConstraints:^(MASConstraintMaker *make) {

         make.center.equalTo(self.view);

         make.size.mas_equalTo(CGSizeMake(400,400));

    }];

}

//exp2: 上下左右边距都为10

-(void)exp2{

    UIView *view = [UIView new];

    [view setBackgroundColor:[UIColor redColor]];

    [self.view addSubview:view];

    [view mas_makeConstraints:^(MASConstraintMaker *make) {

        make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));

        //  make.left.equalTo(self.view).with.offset(10);

        //  make.right.equalTo(self.view).with.offset(-10);

        //  make.top.equalTo(self.view).with.offset(10);

        //  make.bottom.equalTo(self.view).with.offset(-10);

    }];

}

//exp3 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10

-(void)exp3{

    UIView *view1 = [UIView new];

    [view1 setBackgroundColor:[UIColor redColor]];

    [self.view addSubview:view1];

    UIView *view2 = [UIView new];

    [view2 setBackgroundColor:[UIColor redColor]];

    [self.view addSubview:view2];

    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {

        make.centerY.mas_equalTo(self.view.mas_centerY);

        make.height.mas_equalTo(150);

        make.width.mas_equalTo(view2.mas_width);

        make.left.mas_equalTo(self.view.mas_left).with.offset(10);

        make.right.mas_equalTo(view2.mas_left).offset(-10);

    }];

    [view2 mas_makeConstraints:^(MASConstraintMaker *make) {

        make.centerY.mas_equalTo(self.view.mas_centerY);

        make.height.mas_equalTo(150);

        make.width.mas_equalTo(view1.mas_width);

        make.left.mas_equalTo(view1.mas_right).with.offset(10);

        make.right.equalTo(self.view.mas_right).offset(-10);

    }];

}

转载于:https://www.cnblogs.com/xuan-yuan/p/5430227.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值