iOS中的AutoLayout使用实践总结
前言
AutoLayout非常强大也非常易用,可读性也很强,加上各种第三方AutoLayout库,让你布起局来犹如绷掉链子的狗!但在使用中也有各种各样的问题,下面就来给大家详细介绍下。
AutoLayout问题
- 布局冲突
- 固有尺寸冲突
- 布局和固有尺寸冲突
主要概念
- 固有尺寸intrinsicContentSize(意思就是说我知道自己的大小,如果你没有为我指定大小,我就按照这个大小来。)
- hugging,compress
- priority
- constraint:equal,unequal
一个UIView显示,需要有2个元素,position&size。AutoLayout可以确定view的这两个,so不用frame。
1、布局遇到的问题
布局绝对冲突:
eg设置了view的左右,然后又有个width,造成冲突
解决方案:
1.设置优先级(低优先级constraint没有用到的时候的时候系统默认忽略)
2.删除没有的constraint(常用)
2、布局模糊冲突
假设UIView2的宽度不能超过50。当UIView1宽度小于50的时候,二者等宽;
当UIView1宽度大于50的时候,UIView2不受UIView1宽度的影响。
于是给UIView2加上一条约束:宽度<=50。这时候冲突来了:
因为UIView1的宽度是定好的,而UIView2和UIView1等宽。那么UIView2的宽度就是确定的。
so当宽度>50的时候,就是冲突,<=50的时候就不是冲突
解决方案:
equalwidthpriority设置低一些,这样让View2先满足<=50的constraint,当他的width<=50的时候equalwidth生效
enum{ UILayoutPriorityRequired=1000, UILayoutPriorityDefaultHigh=750, UILayoutPriorityDefaultLow=250, UILayoutPriorityFittingSizeLevel=50, };
1、intrinsic冲突
contentHugging/contentCompressionResistance设置优先级解决intrinsicContentSize
- Hugging(不想填充空间)
- Compression(不想被挤压)
- 有这两个特性的view一定实现了intrinsicContentSize
- Hugging默认priority=250
- Compression默认priority=750
- 其他constraint默认priority=1000(最大)
当constraint.priority>hugging.priorityView会被拉伸
当constraint.priority
当constraint.priority>compression.priorityView会被挤压
当constraint.priority
egUILabel有intrinsicContentSize那么UILabel的size就用它,
如果有constraint设置了size那么使用constraint的
UILabel1、和UILabel2布局:
距离上边栏都是50点。UILabel1与左边栏距离为10,UILabel2左面距离UILabel1为10点。
因为都具有Intrinsic属性,所以不需要指定size,位置应该也明确了。
再给UILabel2加一条约束,右侧距离右边栏为10点。(如果view没有intrinsicContentSize,那么右边的view会被拉伸)
因为UILabel有intrinsicContentSize所以2个Labe必须有一个要被拉伸
*1个label使用自己的intrinsic,另一个填充其他空间
使用场景
1、没有intrinsicContentSize的view使用priority,将模糊冲突改变成条件布局
2、有intrinsicContentSize的view
改变huggingorcompression的priority,解决intrinsic冲突
虽然有intrinsic只要给出origin和size就可以了,可是使用unequalconstraint完善布局,避免警告
主要接口&属性
UILabel的preferredMaxLayoutWidth,如果有多行要设置正确的preferredMaxLayoutWidth,来得到正确的intrinsicContentSize
systemLayoutSizeFittingSize调用intrinsicContentSize
layoutIfNeed如果有布局变化强制刷新
当视图的内在内容改变时,需要调用invalidateIntrinsicContentSize,让系统知道在下次布局时重新计算intrinsicContentSize
//原有的视图尺寸和现在的不相符, -(void)layoutSubviews{ [superlayoutSubviews]; _collectionView.frame=self.bounds; if(!CGSizeEqualToSize(self.bounds.size,[selfintrinsicContentSize])){ [selfinvalidateIntrinsicContentSize]; } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。