Auto Layout + Manual Layout 混用

Stella981
• 阅读 780

约束代码混用的问题

无数人趟过此坑,大部分人在坑中一蹶不振,小部分人爬起来也是跌跌撞撞。

有很多人都说auto layout和manual layout的坐标设置是不能混用的,会导致出现布局问题。首先声明一点,autolayout和manuallayout是可以混用的。用的时机很重要,auto layout和manual layout有各自的生命周期和作用域,区分他们两个的作用时间很关键,头脑中一定要清楚你所添加的每条约束,在什么时间场合,会造成什么后果。否则,布局就会和预想的不同,各种奇怪的布局问题也就接踵而至。

1)视图的生命周期顺序

我们在controller视图上面用auto layout添加了一个subview,并在各个系统调用声明周期方法中做了打印处理,结果如下:

Auto Layout + Manual Layout 混用

其中前面带有“-”符号的表示的是subview视图的打印。

autolayout的作用范围是从上往下第三个方法-updateConstraints一直到viewDidLayoutSubviews,这期间,系统是通过view上的约束来计算view上的布局。而我们一般习惯将布局写在viewDidLoad里面,这就是我们为什么总是无法用manual layout的方法去修改我们的布局。

要想修改布局,必须要在autolayout结束之后才会起作用,否则会被系统将我们的布局按照autolayout重新刷新,从上面我们可以看到,我们可以在子视图的-layoutSubviews和-drawRect方法里面修改子视图的布局,但是一般视图为了重用不会在自己的类里面将frame写死,这样我们只有通过controller的viewDidAppear方法修改视图的frame。但是这样也有问题,在viewDidAppear里面修改布局,我们可以看到一个明显的延迟,系统调用次序使然,我们无法去改变。除此之外,如果我们更新了视图的autolayout,会导致视图重新调用updateViewConstraints方法,viewDidAppear在进入页面的时候却只调用一次,结果就是subview又恢复了原来的样子。

所以我的建议就是不要同时manual layout+auto layout去控制同一个视图。始终记得如果用了auto layout去控制了一个视图,那么就要坚持用下去。

2)何为混用

我觉得混用的说法不是对于某一个视图说的,是说我们整个布局当中交叉使用了manual layout + auto layout,比如我们可以用auto layout布局viewA,然后用manual layout 布局B,然后将A与B用两者其一的方式,添加到共同的父viewC上,这就是我所认为的混用。Auto Layout + Manual Layout 混用

那么它的意义是什么呢?不同view的复杂度决定了我们采取哪种方式来对其布局,我们在开发中有可能会遇到某些流式的布局,我们用autolayout可以行云流水,但是对于某个视图当中极其复杂的小控件的布局,auto layout显然要写不少的一大段,当两者组合时也就是混用的意义所在。

3)如何混用

混用的风险其实一点不比它带来的好处小,首先解释一个名字

NSAutoresizingMaskLayoutConstraint

这个类型和NSLayoutConstraint 功能类似,它是个私有类,我们无法获取到,因为苹果ios6之后推出了auto layout技术,但是还想兼容原来的autoresizing,所以它将autoresizing转化为了约束,转化后的约束类型就是NSAutoresizingMaskLayoutConstraint,这就有可能导致系统为我们添加了许多我们无法预料的约束。Auto Layout + Manual Layout 混用

我们有时候会发现我们的约束没有写全,但是布局却很好,千万不要太得意,这只是系统帮你完成你该做的,这种情况固然对我们有好处。但是在manual layout +  auto layout布局中就会发生大问题,系统不懂我们是在故意不写它的约束(因为我们打算手动布局这一块的视图),它就默默帮我们加上了谁都不知道的约束,并为自己的机智暗自欣喜。我们要明确告诉它我不需要你的帮助才行。

UIView里translatesAutoresizingMaskIntoConstraints属性就是用来控制是否允许系统做这样的转化,默认是YES。所以我们要把它设置为NO,然后将你漏掉的约束统统加上。

怎样算作完备的约束呢,我的建议是把视图层次分清楚,每个层次系统内部使用统一的布局方案,并保证系统内的的约束完整。

这是一个视图的层级拓扑结构(原谅我又盗图了,凑合看吧),如果我打算在做黄箭头位置的视图布局时采用auto layout,其他采用manual layout那么我只需保证它及它下面的两个子视图之间的约束完整就可以了,他们三个可以当做一个小的系统,系统内的约束只与他们自己相关,像下面两个红线连接的视图间的约束就是不允许添加的。

Auto Layout + Manual Layout 混用

图:错误的约束关系

4)最后

以上就是我想说的,混用这种手段还是希望大家谨慎使用为好,最后总结一下混用的关键点

1.首先要确保在你打算使用手写auto layout为view布局前,将其translatesAutoresizingMaskIntoConstraints属性设为NO

2.不要用对同一个视图同时使用manual layout +  auto layout

3.确保你的约束在其系统内完整无缺失。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这