AutoLayout代码布局使用大全—一种全新的布局思想

2024-01-12 17:58

本文主要是介绍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

};



以上是官方API对约束关系的描述,其中NSLayoutAttributeLeading,NSLayoutAttributeTrailing,实际上等同于left和right,据说是阿拉伯国家的使用习惯。
 可以根据以上枚举看出约束关系主要就是上下左右,宽度,高度,横坐标中心,纵坐标中心。


typedefNS_ENUM(NSInteger, NSLayoutRelation) {

    NSLayoutRelationLessThanOrEqual = -1,

    NSLayoutRelationEqual =0,

    NSLayoutRelationGreaterThanOrEqual =1,

};


  约束描述主要就是<= == >=  主要是用于不确定大小和坐标的约束,autolayout适配的灵活性和动态性主要来源于这个约束关系。
  约束系数multiplier和约束常数constant主要是计算约束关系最终结果的,遵循公式"view1.attr1 = view2.attr2 * multiplier + constant"

  以上就是所有布局的约束来源,可以看到使用起来非常的方便,由于要想准确的将一个View动态布局,
有时候往往需要设置好几个约束来定位view的位置,所以这种代码写起来往往比设置frame更加的冗长,
好在文文介绍的UIView+AutoLayout可以替你分担。
   
  回归主题,通过以上代码可以看到,由于只需要设置一个view的大小,所以不需要约束源,toItem
设为nil,那么约束源的关系自然就是没有关系了,第二个Attribute设为NSLayoutAttributeNotAnAttribute。
   按照这种思维,其实我们就可以动态绑定一个view和另一个view的大小,实际上却很少这么用,
为什么呢?之后会讲到。

   2.位置间的约束
   先来看看UIView+AutoLayout的实现。
   [View1autoPinEdge:ALEdgeLefttoEdge:ALEdgeLeftofView:View1withOffset:5];
   UIView+AutoLayout底层原生的实现

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 


原文链接: http://blog.csdn.net/u013263917/article/details/42283661

这篇关于AutoLayout代码布局使用大全—一种全新的布局思想的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/598689

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

hdu1496(用hash思想统计数目)

作为一个刚学hash的孩子,感觉这道题目很不错,灵活的运用的数组的下标。 解题步骤:如果用常规方法解,那么时间复杂度为O(n^4),肯定会超时,然后参考了网上的解题方法,将等式分成两个部分,a*x1^2+b*x2^2和c*x3^2+d*x4^2, 各自作为数组的下标,如果两部分相加为0,则满足等式; 代码如下: #include<iostream>#include<algorithm

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]