AutoLayout代码布局使用大全—一种全新的布局思想
相信ios8出来之后,不少的ios程序员为了屏幕的适配而烦恼。相信不少的人都知道有AutoLayout
这么个玩意可以做屏幕适配,事实上,AutoLayout不仅仅只是一个为了多屏幕适配的工具,
它真正的意义所在是给了程序员一种全新的布局思想。
本文主要依据真实项目实例从三个方向全方位讲解AutoLayout的使用大全。
一。AutoLayout布局原理和语法
二。约束冲突和AutoLayout动画处理
三。AutoLayout布局思想,约束链的控制。
本文讲解的内容和代码主要依赖于一个名为UIView+AutoLayout的分类。文章末尾将会附上下载链接。
一。AutoLayout布局原理和语法
笔者在写这篇文章之前,阅读过不少关于AutoLayout教程的文章。其中有一句话尤为深刻,
学习AutoLayout之前,必须要完全抛弃传统的frame属性,先完成思想的扭转学习起来方能事半功倍。
AutoLayout是苹果ios6出来的东西,与传统的Frame属性不同。每一个view对象都有一个frame属性,
frame属于CGrect对象,通过苹果的Api可以得知,CGrect其实是一个结构体。
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;一个是控制坐标的CGPoint,一个是控制大小的CGSize。
而AutoLayout是通过约束来实现布局的。一个view一旦使用了AutoLayout约束,
那么它的frame将永远都是0.
所以在使用AutoLayout之前需要两个准备工作。
1.设置
translatesAutoresizingMaskIntoConstraints为NO。
2.如果是viewControl则AutoLayout适配写在
- (void)updateViewConstraints中。
如果是view则AutoLayout适配写在
- (void)updateConstraints中。实际上,这也正是AutoLayout好处之一,可以集中将一个controller和
view的适配在一个方法中。
AutoLayout语法主要分三类
1.设置size。
先来看看UIView+AutoLayout的实现。
[ViewautoSetDimension:ALDimensionWidthtoSize:30];
UIView+AutoLayout底层原生的实现
NSLayoutConstraint *constraint = [NSLayoutConstraintconstraintWithItem:selfattribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nilattribute:NSLayoutAttributeNotAnAttributemultiplier:0.0fconstant:size];
[View addConstraint:constraint];
任何一个AutoLayout语法都是通过创建一个NSLayoutConstraint约束对象添加到view的约束中去的。
创建一个AutoLayout需要七个参数,他们分别是(1)WithItem:被约束对象
(2)第一个attribute:被约束对象的关系 (3)relatedBy:约束描述 (
4)toItem:约束源 (5)第二个attribute:约束源的关系 (6)multiplier:约束系数
(7)constant:约束常数
在官方的api中,对约束有一个计算公式
/* Create constraints explicitly. Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant"
下面具体讲解参数在NSLayoutConstraint API中的对应属性。
typedefNS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft =1,
NSLayoutAttributeRight,
NSLayoutAttributeTop,
NSLayoutAttributeBottom,
NSLayoutAttributeLeading,
NSLayoutAttributeTrailing,
NSLayoutAttributeWidth,
NSLayoutAttributeHeight,
NSLayoutAttributeCenterX,
NSLayoutAttributeCenterY,
NSLayoutAttributeBaseline,
NSLayoutAttributeLastBaseline =NSLayoutAttributeBaseline,
NSLayoutAttributeFirstBaselineNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeLeftMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeRightMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeTopMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeBottomMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeLeadingMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeTrailingMarginNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeCenterXWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeCenterYWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeNotAnAttribute =0
};
typedefNS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1,
NSLayoutRelationEqual =0,
NSLayoutRelationGreaterThanOrEqual =1,
};
NSLayoutConstraint *constraint = [NSLayoutConstraintconstraintWithItem:self
attribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqual
toItem:View2attribute:NSLayoutAttributeLeftmultiplier:1.0fconstant:5];
[View1 addConstraint:constraint];
根据上文讲解的各参数的含义可知,以上方法的意思就是约束view1的最左边到view2的最左边的距离是5(因为约束系数是1).
3.约束对齐
先来看看UIView+AutoLayout的实现。
[view1autoAlignAxisToSuperviewAxis:ALAxisVertical];
UIView+AutoLayout底层原生的实现
NSLayoutConstraint *constraint = [NSLayoutConstraintconstraintWithItem:selfattribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqua toItem:view1.superview
attribute:NSLayoutAttributeCenterXmultiplier:1.0fconstant:0.0f];
根据上文讲解的各参数的含义可知,以上方法的意思就是约束view1的横坐标中心在view1的父view中居中.
因为前文说过,所有的约束都是创建一个相同的NSLayoutConstraint对象来实现。所以代码都是大通小易。
以下主要讲解一下UIView+AutoLayout这个分类的使用方法。
根据以上的约束三种用途,UIView+AutoLayout对应的方法主体上也分为三类。
1.设置size类(以autosetdimension开头)
以下是ALDimension枚举
typedefNS_ENUM(NSInteger, ALDimension) {
ALDimensionWidth =NSLayoutAttributeWidth, // the width of the view
ALDimensionHeight =NSLayoutAttributeHeight // the height of the view
};
2.位置约束(以autopin开头)
以下是ALEdge枚举
typedefNS_ENUM(NSInteger, ALEdge) {
ALEdgeLeft =NSLayoutAttributeLeft, // the left edge of the view
ALEdgeRight =NSLayoutAttributeRight, // the right edge of the view
ALEdgeTop =NSLayoutAttributeTop, // the top edge of the view
ALEdgeBottom = NSLayoutAttributeBottom, // the bottom edge of the view
ALEdgeLeading = NSLayoutAttributeLeading, // the leading edge of the view (left edge for left-to-right languages like English, right edge for right-to-left languages like Arabic)
ALEdgeTrailing = NSLayoutAttributeTrailing // the trailing edge of the view (right edge for left-to-right languages like English, left edge for right-to-left languages like Arabic)
};
3.约束对齐(autoAlign开头)
以下是ALAxis枚举
typedefNS_ENUM(NSInteger, ALAxis) {
ALAxisVertical = NSLayoutAttributeCenterX, // a vertical line through the center of the view
ALAxisHorizontal = NSLayoutAttributeCenterY, // a horizontal line through the center of the view
ALAxisBaseline = NSLayoutAttributeBaseline // a horizontal line at the text baseline (not applicable to all views)
};
第一节小结:主要讲解了一下AutoLayout底层实现原理和UIView+AutoLayout的封装原理。
二。AutoLayout约束冲突和动画处理
以上的这个页面就是完全用的AutoLayout布局,整体结构就是这样,顶部的label1和右上角按钮button1,
中间的imageview1和label2,下方两个cellview1和cellview2,再下面一个button2,
最下面的小提示忽略不计。
cellview1和cellview2是自定义的view,里面的一些image view和label都是它的子view。
重点:当一个父view1有了一个子view2,并且子view2有了子view3,那么在约束view3的时候,
如果它的父view不是最高层的那个view,那么view3的约束会对它的父view产生约束影响。
这一个规则确实让人很难摸清头脑,笔者这里不再详细说明,希望读者在遇到约束冲突的时候
逐渐摸清这个规则。
AutoLayout的动画处理。
假如一个view使用了AutoLayout约束布局之后,这个时候如果对这个view做一个动画处理,
按照传统的做法是改变它的一些属性,在平移动画中主要是改变它的frame坐标,
但是在AutoLayout中frame都是0应该如何处理呢。这里笔者由难到易提供三种解决方案。
1.使用[self.viewlayoutIfNeeded]方法动态刷新约束,笔者认为这个对初学AutoLayout的人
来说是最难的。
2.改变view的bounds属性。这个网上有资料,在AutoLayout中bounds属性是有效的。
这个可能相对好解决一点。
3.改变view的transform属性,比如说网上平移10个距离,可以这样写self.transform = CGAffineTransformMakeTranslation(0, -10); 相信这个是最简单也是最好处理的了。
三。AutoLayout布局思想,约束链的控制
还是使用这个页面加上UIView+AutoLayout来详细讲解。
比如说我要布局cellView1中最左边那个招商银行logo的imageview。
使用UIView+AutoLayout可以这样写。
[imageview autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:self withOffset:5];
[imageview autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:self withOffset:5];
[imageview autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:self withOffset:5];
[imageview autoPinEdge:ALEdgeRight toEdge:ALEdgeLeft ofView:self withOffset:35];
基本上任何的view都可以分别对它的上下左右使用四个位置约束来确定它的位置,
这四行代码的意思本别就是
imageview顶部距离父view顶部间距5,image view底部距离父view底部间距5,
imageview左侧距离父view左侧间距5,imageview右侧距离父view左侧间距35,
这样子的话,假如父view的高度是40的话,那么imageview的size不需要设置,
自然而然的被这四个约束为(30,30).
这看起来没什么不妥,实际上已经是约束过度了。当父view的高度发生变更的时候,
imageview的高度就会因为顶部和底部的约束而动态计算,假如父view高50,
那么imageview的size就是(30,40),这个时候假如是一张方形图片就会变形,
实际上这并不是AutoLayout的精髓。
再看下面这种约束方式
[ImageViewautoSetDimensionsToSize:CGSizeMake(30,30)];
[ImageViewautoPinEdge:ALEdgeLefttoEdge:ALEdgeLeftofView:selfwithOffset:5];
[ImageViewautoAlignAxisToSuperviewAxis:ALAxisHorizontal];
这三行代码的意思是,约束imageview的固定大小(30,30),
约束imageview左侧距离父view左侧间距为5,约束imageview的纵坐标轴线与父view纵坐标轴线对齐。
通过以上三个约束不难看出,无论父view如果改变大小和位置,
image自身的形状和父view的相对位置都是固定的。
总结:AutoLayout真正的语法只有一个方法,只要理解这个方法的七个参数分别所代表的含义就不难理解AutoLayout的实现原理。所以对于程序员来说,重要的并不是这种布局方式用代码写起来有多么的冗长,因为有不少的三方库可以帮助你简写代码,实际上我们真正要掌握的是AutoLayout的这种布局思想,心中对一个view布局的时候心中都应该要有一条约束链,只有这样,你的布局约束将会越来越精简,越来越准确,也越来越适配。
因为笔者自己也是刚刚接触AutoLayout,以上只是粗略的讲解一下自身的学习心得,笔者极力推荐UIView+AutoLayout这个库来使用AutoLayout,因为封装都比较形象,并且接近底层,对理解AutoLayout的原理和掌握内涵更加的有益。
以下是三方库的资源链接,http://download.csdn.net/detail/u013263917/8315971
AutoLayout代码布局使用大全—一种全新的布局思想相关推荐
- css浮动布局自适应,CSS 几种常用自适应布局
通过阅读和实践,我对几种常用的布局样式有了一定的了解,也稍微总结了一下原理,若有不对请大家纠错.谢谢 我理解的[两列布局]左边固定和右边自适应,或者右边固定左边自适应的原理是: 1.设置固定区域的宽度 ...
- html中页面布局主要有,4种Html页面布局
有些人经常问我这样的一些问题,就是如何才能在页面上精确的控制元素,为什么我的页面总是一直在飘呢,我在这里只想说,关于页面布局,标准也很重要. (1)流体布局 流布局与固定宽度布局基本不同点就在于对网站 ...
- java list布局_java – 使用2种不同的布局重用Android Listvi...
我已经了解到,为了最大限度地提高Android列表视图的效率,您应该只需要尽可能多的充满"行"视图,以适应屏幕.一旦视图移出屏幕,您应该在getView方法中重用它,检查conve ...
- html三列布局中间固定,常见的三列布局(左右固定宽度,中间自适应)
实现css中的三列布局,左右固定宽度,中间自适应.三列布局方式的关键是怎么样才能使得在伸缩浏览器窗口的时候让中间的子元素宽度改变.比较常见的实现方案是:定位,浮动,css3中新特性flex布局,以及流 ...
- CSS3与页面布局学习总结(四)——页面布局大全BFC、定位、浮动、7种垂直居中方法...
目录 一.BFC与IFC 1.1.BFC与IFC概要 1.2.如何产生BFC 1.3.BFC的作用与特点 二.定位 2.2.relative 2.3.absolute 2.4.fixed 2.5.z- ...
- .NET Core跨平台的奥秘[下篇]:全新的布局
从本质上讲,按照CLI规范设计的.NET从其出生的那一刻就具有跨平台的基因,这与Java别无二致.由于采用了统一的中间语言,微软只需要针对不同的平台设计不同的虚拟机(运行时)就能弥合不同操作系统与处理 ...
- 一种全新的深亚微米IC设计方法
一种全新的深亚微米IC设计方法 类别:电子综合 阅读:910 本文分析了传统IC设计流程存在的一些缺陷,并且提出了一种基于Logical Effort理论的全新IC设计方法. 众所周知 ...
- cad字体库大全2485种字体 附使用教程|cad字体库大全免费版
在CAD工程设计中,设计图纸是不可缺少的核心,而不同的设计图纸所需要的字体也是不同的,若缺少相对应的字体,那么设计图纸文字显示就会产生乱码,严重的话还会影响布局,为此小编带来了cad字体库大全2485 ...
- NeurIPS 2021 | 寻MixTraining: 一种全新的物体检测训练范式
来源:专知 本文附论文,建议阅读5分钟物体检测是计算机视觉中的基础课题. MixTraining: 一种全新的物体检测训练范式 论文链接: https://www.zhuanzhi.ai/paper/ ...
最新文章
- 机器学习新手们 我这有本秘笈要不要?
- Windows上安装AD域控制器注意事项及常见问题处理办法
- VTK:baking烘焙阴影贴图用法实战
- Java常用类(4)--System类
- c++ linux 线程等待与唤醒_Linux驱动程序基石-POLL机制(附.视频)
- 规模化敏捷框架何从入手?这篇文章把SAFe讲透了!
- Linux 安装 OFFICE 2007
- Oracle数据库REDO损坏ora-00333修复手札
- 【JavaScript】17 - DOM
- win7修改计算机名访问被拒绝访问,今天解答win7无法更改注册表拒绝访问的解决介绍...
- MySQL NDB Cluster部署方案与实践
- 《计算机网络技术》第三章课后习题答案(全)
- postgres/pgadmin的使用
- [摘] 什么是网络流量劫持?揭秘详解黑客劫持的攻击手段与防御方法 (一)
- 智能优化算法(源码)-蜉蝣算法(Mayfly Algorithm,MA)
- 100个python算法超详细讲解:个人所得税
- PowerDesigner 把设计图导出成图片
- tomcat打包war,jar部署
- VM15pro安装MacOS10.15.1系统(超详细,可用)
- 使用clipboard.js实现移动端页面一键复制功能 + 弹出复制成功提示
热门文章
- python图片二进制流转换成图片_python将图片二进制数据转换成Django file对象
- php文件名函数,php 获取文件名basename()函数的用法总结
- python程序设计基础考试题库及答案_智慧职教Python程序设计基础题库及答案
- Java 文件压缩与解压缩
- 对实体 quot;useSSLquot; 的引用必须以 ';' 分隔符结尾
- 八十八、Python | 十大排序算法系列(下篇)
- 百度机器翻译已经进化到什么程度?
- 一文详解Google最新NLP模型XLNet
- python 中的理解x[:]
- 【Java报错】Greenplum数据库报错 Value can not be converted to requested type 问题解决(踩坑分享)