在自动布局中使用优先级,除了上一篇自动布局技巧篇-Content Hugging Priority 和 Content Compression Resistance Priority讲到的防压缩或防拉伸情况下会使用,那么还有那些情况下会用到呢?
下面看一个场景,要求实现下面的效果:
假设三个视图分别是View1,View2,View3,最开始是view2距离view1二十个像素,view3距离view2二十个像素,而实际项目中,view2有时候有有时候没有,有的话就是正常情况,像上面三个排列,没有的话,view3会取代view2的位置距离view1二十个像素,
解决上面的问题有很多种方式,比如以下三种:
1 view3是基于view2,如果view2没有,隐藏view2,将view3与view2之间间距约束设为0,并将view2宽度约束设为0
2 view3不基于view2,而是基于view1,距离view1最开始一个距离disView3ToView1(20*2+view2的宽度),当view2没有的时候,隐藏view2,将disView3ToView1约束值设为20,
3 view3既基于view2,又基于view1,就是view3距离view2,view3距离view1都有一个距离为20的约束就是disView3ToView2,disView3ToView1,只不过刚开始view3到view2距离的优先级要高于view3到view1距离的优先级,即disView3ToView2的priority>disView3ToView1的priority,后面如果view2没有了,改变两个距离对应的优先级为,disView3ToView2的priority
前面两种方法本质上是一样的,都是改变约束的值,来改变位置,第三种方式而是通过改变约束优先级的方式实现,在一种情况下,这种约束满足,那么它的优先级就高,另外一种情况下,另一种约束满足,那么另一种约束优先级就高,显然这种场景下,采用优先级的方式更适合,
这里我们主要来看一下view3的约束:
点击其中view3到view2的约束
点击其中view3到view1的约束
注意:
上面本来默认添加一个约束的时候它的优先级是1000,那么按理来说上面那个999没必要改啊,直接让它使用默认值1000就可以啊,为什么我要改成999呢,或者为什么我不使用1000那个数值呢,是有原因的,因为后面我要改变这两个优先级(大的改小,小的改大),如果是1000的话,那么就意味着我可能会将1000改成小于1000的,小于1000的改成1000的,那么这样就会有问题,你用1000的话,你就会发现报下面的错误
原来,具有优先级1000(UILayoutPriorityRequired)的约束为强制约束(Required Constraint),优先级小于1000的约束为可选约束(Optional Constraint),而优先级的修改只允许在可选约束优先级范围内才能修改,换句话说:
不允许将优先级由小于1000的值改为1000
不允许将优先级由1000修改为小于1000的值
也就是只能在小于1000的范围内修改,
所以上面专门把1000改成了999,另一个则是998
下一步:把两个约束拖出来
@property(weak,nonatomic)IBOutletNSLayoutConstraint*view3ToView1Constraint;
@property(weak,nonatomic)IBOutletNSLayoutConstraint*view3ToView2Constraint;
然后修改即可
self.view3ToView1Constraint.priority=999;
self.view3ToView2Constraint.priority=998;
这是一种场景,下面还有一种场景,
要求:正常情况下,上面view和下面view,等宽等高,上面视图宽度变化,下面视图宽度也随着变化,但是下面视图有一个最大宽度250,到达了这个宽度后,便不再增大,
分析:
这里下面的view关键是两个约束
1 和上面的view等宽
2 最大宽度250
如果这两个约束优先级一样的话,那么当上面视图宽度超过250的时候,会报错,实际运行会出现未知情况,
所以两个约束必然要有一个优先级要高些,因为当宽度大于250的时候,最大宽度这个约束得起作用,肯定要比等宽的约束作用力度要大些,所以最大宽度约束的优先级>等宽约束的优先级,还是采用小于1000的形式,防止以后会改变它们,如下:
宽度约束:
等宽约束:
那么可以总结一下什么场景下该使用优先级了:
对于一个视图,正常情况下,它有一个约束constriant1,特殊情况下它又有一个约束constraint2,这个view不管现在处于哪一种情况,只可能是这两个约束中的一个起作用(不一定会相互冲突比如例子2,但同一种情况只可能是其中一个约束在起作用),那么这个时候这个约束的优先级就要高于另外一个,相反一样。
demo地址https://github.com/aszkj/KJAutoLayoutSillDemo