iOS自动布局进阶用法

本文主要介绍几个我遇到并总结的相对高级的用法(当然啦牛人会觉得这也不算什么)。 简单的storyboard中上下左右约束,固定宽高啥的用法在这里就不做赘述了。

autolayout自动布局是iOS6以后出现的,但是在开始的一段时间里大家并不怎么会用,都是一上来先勾掉。之后随着5s,iPhone6的出现屏幕多种多样。用多层if来判断尺寸已经完全hold不住了才开始学习自动布局。

在这之前有个叫自动伸缩的autoresizing属性,这个主要用于一个控件和自己父控件之间的关系。只有autolayout才真正可以在任意两个控件中建立关系。

 如果你不是在董铂然博客园看到本文 请点击查看原文

关于autoresizing

autoresizing需要注意的是 storyboard中设置的约束和手码中设置的约束是相反的。 storyboard图形页面里点的右边的线和下边的线的意思是“固定”

而手码中常用的autoresizingMasks属性中的枚举都是Flexible可“伸缩”的。 所以假如想要让右边和下边的距离固定,在代码中应该设置左边和上边的可伸缩约束。

yellowView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleTopMargin;

有了autolayout之后这个自动伸缩很少用了 一共七个属性。

无,宽可伸缩,高可伸缩,左间距可伸缩,右间距可伸缩,上间距可伸缩,下间距可伸缩

     UIViewAutoresizingNone                 = 0,

     UIViewAutoresizingFlexibleWidth        = 1 << 1,

     UIViewAutoresizingFlexibleHeight       = 1 << 4,

     UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,

     UIViewAutoresizingFlexibleRightMargin  = 1 << 2,

     UIViewAutoresizingFlexibleTopMargin    = 1 << 3,

     UIViewAutoresizingFlexibleBottomMargin = 1 << 5

 每个枚举值都是位移枚举,可以在一行代码中传多个值。

 

关于label的自动识别大小

label想要在界面中显示成这样

意义是下面的控件可以根据上面label的底部进行自动调整。 

这个不是用sizetofit设置的,而是用约束,会在程序运行中数据变了约束立即改变,尺寸也立即改变。

这种设计方法是:

1.设置label的左边和上边的约束,然后再设置下最宽度约束假设是150,把label里面的lines属性设置成0即随意任意多行。 这样里面的文字就会自动换行并且一直显示完,label的背景色也是自动匹配。

2.但是右边还多出了一块。label的右边还有一块蓝色并不是紧紧的挨着。这时就要选中那个宽度的约束 再到右边把Relation由原本的equal改成 less than or Equal 。这时候左边的约束显示变了  变成≤了。

运行之后结果是:这里可以清楚的看到label的右边紧紧挨着边了。

3.但是有时候数据可能为空,一旦为空label的大小就被挤没有了,下面的控件也凌乱了。所以为了保证就算数据没有空当也要留着占位,就找给他设置两个高度约束,一个是大于等于一个是小于等于,包裹成一个范围。 这时候要把上面width的小于等于改成equal。

就像这样 这时候运行效果 遇到大量文字和没文字的两种效果是

起到了占位的作用。即使文字没有地方还在。

 

关于Constraints在哪找的问题

左边的图constraints有的在label节点下有的在View节点下,究竟是什么原因决定了constraints在哪个节点下面?

是看这个约束是否依赖了别的控件,如果就是自己设置固定宽高啥的不关系到别人那就是在自己下面。如果依赖谁设置了间距,那这个约束就会放在自己和依赖的控件的最小公共父控件下。

如图   

 

 

关于手码编写autolayout约束

storyboard界面里面的托拉拽固然方便但是不能批量操作(董铂然原创),假如有类似的30个小控件,storyboard就太麻烦了,手码的话一个循环就完事了

手码创建就是所谓的那七个参数的长的像句子似得方法

之后再在相应的节点下添加约束,有添加一个和添加一组 两种方法。

// 高度约束(添加到yellowView身上)NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:50];[yellowView addConstraint:heightConstraint];// 间距约束(添加到self.view身上)CGFloat margin = 20;[self.view addConstraints:@[// 左边[NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:margin],// 右边[NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant: - margin],// 底部[NSLayoutConstraint constraintWithItem:yellowView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant: - margin]]];
}

  

这里用到了一个核心公式,任何两个控件间的约束都可以通过这个公式算出

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

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

还有为了避免和系统生成的自动伸缩的约束不冲突 一般加上这句

系统默认这个属性是yes

 

 

关于VFL语言 

Visual Format Language,翻译过来是“可视化格式语言”  是苹果公司为了简化Autolayout的编码而推出的抽象语言
相当于打出象形文字似得,而且要全在字符串里写,遇到错误比较难调,但是相对来说代码精简了不少。
然后在添加约束的时候就会用到系统提供的另外一种方法。
    NSArray *contraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:metrics views:views];

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

上面的方法中传到的两个参数metrics 和 views 是两个字典。(董铂然原创) 第一个字典metrics是用来告诉系统里面的每一个值对应哪个字母 

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

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

括号里可以传多个值逗号隔开

 

关于常用的手码约束的第三方框架

有 Masonry 和 UIView+Autolayout

框架地址是:

https://github.com/Masonry/Masonry 

https://github.com/smileyborg/UIView-AutoLayout

 

UIView+Autolayout框架

这个相对于masonry,是个轻量级的框架易于上手,里面一共也就两个文件。也非常好用,都是用auto开头。适用于约束不经常改变的项目

事例用法:

直接设置四周的间隔距离

[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)]; //直接设置四周的间隔距离

设置三个间隔,然后再添加个高度,

[self.yellowView autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(20, 20, 20, 20)excludingEdge:ALEdgeTop]; // 让顶部约束无效[self.yellowView autoSetDimension:ALDimensionHeight toSize:100]; // 自己再添加个高度约束正好四个

也可以直接设置大小

[self.yellowView autoSetDimensionsToSize:CGSizeMake(200, 200)];

总之还有很多用法,在这不一一介绍了,大概就是这个代码风格。有兴趣的可以去上面说的那个github地址上仔细查看。

 

 

Masonry框架

这个框架是重量级的里面好多文件,难于上手,但是用熟练了的话比上面那个牛X,适合于约束要经常改变的项目。
示例代码:
添加距离四个方向20的间隔约束
[yellowView mas_makeConstraints:^(MASConstraintMaker *make) {// make代表yellowView// 添加约束make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(20, 20, 20, 20));}];

下面这个是更新约束,非常方便会自动识别上左下右的属性来更改。

[self.yellowView mas_updateConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.view.mas_left).offset(100);make.top.equalTo(self.view.mas_top).offset(100);make.right.equalTo(self.view.mas_right).offset(-100);make.bottom.equalTo(self.view.mas_bottom).offset(-100);}];

还有一些别的属性用法。

主要是作者设置的属性比较多这张图摘自他的github,有兴趣可以去github仔细看

关于想给约束改变添加动画。

因为约束的改变是瞬时操作和frame的概念不一样,所以把约束的代码放在动画的block里是无效的
错!
正确做法是,把约束写在外面面,然后在动画的block中包裹 layoutifneed
对!
如果你不是在董铂然博客园看到本文 请点击查看原文
对了还有一个注意点是:需要依赖父控件的约束要在添加了父控件之后再写。
有什么不同的看法欢迎评论。本博客所有文章均原创,转载请注明出处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows系统与Linux系统下的硬盘分区操作

以下内容源于网络资源的学习与整理&#xff0c;如有其侵权请告知删除。 之前在uboot中利用fdisk命令对X210开发板的iNand进行分区时&#xff0c; 因为不小心在uboot中利用“fdisk -c 1”&#xff08;1对应着sd卡&#xff0c;0对应着iNand&#xff09;对sd卡也分区了&#xff…

您应该了解的 Windows Azure 网站在线工具

&#xfeff;&#xfeff;编辑人员注释&#xff1a;本文章由Windows Azure 网站团队的软件开发者 Amit Apple 撰写。 如果想要了解并亲身参与计算资源管理&#xff0c;那么您一定会很高兴得知这一消息&#xff1a;Windows Azure 网站现在提供一些非常有用的在线工具&#xff0c…

【自己给自己题目做】:如何在Canvas上实现魔方效果

最终demo -> 3d魔方 体验方法&#xff1a; 浮动鼠标找到合适的位置&#xff0c;按空格键暂停选择要翻转的3*3模块&#xff0c;找到相邻两个正方体&#xff0c;鼠标点击第一个正方体&#xff0c;并且一直保持鼠标按下的状态直到移到第二个正方体后放开&#xff0c;比如下图&…

彻底搞懂硬盘相关的概念

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 硬盘结构&#xff08;机械硬盘和固态硬盘&#xff09;详解 简单理解磁盘结构_Guanngxu的博客-CSDN博客_磁盘的结构 硬盘基础知识_Forskamse的博客-CSDN博客 硬盘知识笔记整理_落子摘星的博客-CSDN…

windows修改远程桌面RDP连接数

windows 2003在默认情况下最多只允许两个用户进行远程终端连接&#xff0c;当达到两个远程桌面连接的到时候&#xff0c;再有人尝试连接&#xff0c;就会提示已经达到最大终端数&#xff0c;无法连上了。 一、windows2003终端连接数修改 1.1终端服务安装和连接数设置 导读&…

ubuntu下数据库的导入导出

2019独角兽企业重金招聘Python工程师标准>>> 一.导出远程数据库 例如 sudo mysqldump -h 172.16.1.211 -u haha -p123 -P3307 app>app.sql 二.导入.sql文件的 到数据库 1.create database xxx(创建一个名称是xxx的数据库) 2. use xxx(切换到该数据库下) 3. sou…

烧录文件、复制文件有什么区别?

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 镜像数据烧录和复制粘贴有什么区别&#xff1f;用 rufus 将镜像烧录到 U 盘和直接复制粘贴 把程序烧入设备和把程序复制到设备的linux系统中有什么区别&#xff1f; - 知乎 前言 之前思考过&#…

php中preg_match用户名正则实例

例子,字母、数字和汉字 代码如下复制代码 if(preg_match("/[ .,:;*?~!#$%^&)(<>{}]|]|[|/|\|"||/",$user)){ echo 不要在名字里面整些特殊符号&#xff0c;请只使用字母、数字和汉字&#xff0c;当然要你的浏览器要选简体中文GB2312哟&#xff0c;千…

MBR分区表的简介

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 &#xff08;1&#xff09;S5PV210 Uboot开发与移植01&#xff1a;Uboot概述_麦兜的学习笔记的博客-CSDN博客 &#xff08;2&#xff09;Linux系统下的硬盘分区、格式化与挂载_天糊土的博客-CSD…

Heartbeat

Heartbeat心跳信息传递&#xff1a;UDP UnicastUDP MulticastUDP broadcastSerial Cable组播地址用于标识一个IP组播域。IANA(internet assigned number authority)把D类地址空间分配给IP组播&#xff1b;其范围是从224.0.0.0至239.255.255.255。永久组播地址&#xff1a;224.0…

Redis配置文件参数说明

配置文件参数说明: 1. Redis默认不是以守护进程的方式运行&#xff0c;可以通过该配置项修改&#xff0c;使用yes启用守护进程 daemonize no 2. 当Redis以守护进程方式运行时&#xff0c;Redis默认会把pid写入/var/run/redis.pid文件&#xff0c;可以通过pidfile指定 pidfile …

movi命令(do_movi函数的源码分析)

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 一、do_movi函数分析 当执行movi相关命令时&#xff0c;实际执行的是do_movi函数。 x210 # help movi movi init - Initialize moviNAND and show card info movi read {u-boot | kernel} {addr} - Read …

[LeetCode]Search Insert Position

原题链接&#xff1a;http://oj.leetcode.com/problems/search-insert-position/ 题意描述&#xff1a; Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You …

如何将镜像烧写至iNand(fastboot命令的源码分析)

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 u-boot sdfuse命令烧录分析----从SD卡加载内核_white_bugs的博客-CSDN博客 一、将镜像文件烧写至iNand的步骤 步骤1&#xff1a;完成准备工作。 &#xff08;1&#xff09;准备fastboot相关软件包…

计算机二级考试Access教程

本教程对编程语言各种要点进行详细的讲解介绍&#xff0c;从基础知识到实用技术功能&#xff0c;内容涵盖了从数组&#xff0c;类等基本概念到多态、模板等高级概念。教程本着实用的原则&#xff0c;每一小节都结合了可以笔试、面试的常见程序实例&#xff0c;以便从第一课开始…

为Elasticsearch添加中文分词

Elasticsearch的中文分词很烂&#xff0c;所以我们需要安装ik。首先从github上下载项目&#xff0c;解压&#xff1a; cd /tmpwget https://github.com/medcl/elasticsearch-analysis-ik/archive/master.zipunzip master.zipcd elasticsearch-analysis-ik/然后使用mvn package …

mmc命令(do_mmcops函数的源码分析)

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 在文章如何将镜像烧写至iNand&#xff08;fastboot命令的源码分析&#xff09;中写到&#xff0c;system、kernel、bootloader的烧写都是write_to_ptn函数直接或间接调用do_mmcops函数来完成的。这里简单分…

你知道自己执行的是哪个jre吗?

多个JRE 我在做《Java日志工具之java.util.logging.Logger》的DEMO时&#xff0c;修改java.util.logging.Logger的配置文件&#xff0c;怎么修改都不起作用&#xff0c;因此打印了系统属性"java.home"&#xff0c;才知道自己使用的是 C:\Program Files\Java\jre7 &am…

lvs-健康检查方式

一、TCP 4层检查virtual_server 192.168.2.213 80 { delay_loop 6 lb_algo wlc #采取权重式最少链接分配 lb_kind DR #采取DR模式protocol TCPreal_server 192.168.2.220 80 { TCP_CHECK { #TCP 检查 connect_port 4000 con…

Leetcode编程事宜

中文网站 题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 英文网站 Problems - LeetCode 账号相关 账号是主邮箱账号&#xff0c;密码是“姓的拼音身份证后6位”。 编程计划 &#xff08;1&#xff09;先从简单的题目刷起。 &#xff08;2&#xff09;不要求每道题都要解答…