故事从一年前提及,当时因为接到一个新项目开发任务开发以前想了想之前项目UI
布局方式大多数都是frame
计算有的也用到masonry
。
frame
你们都知道适配各类屏幕很是繁琐各类坐标size
计算代码很冗余后期难以维护。
masonry
开源给iOS开发者带来福音简化了AutoLayout
使用方式,可是我以为masonry
还不足够快捷方便(有的api不知道什么意思学习成本比较高),尤为是动态布局masonry
更新约束至关不方便,后来就决定本身开发AutoLayout
库也就是今天WHC_AutoLayoutKit。javascript
在阅读以前能够先看看例子项目:github.com/netyouli/WH… java
UITableViewCell
高度模块带缓存高度WHC_StackView
模块(目的替代系统UIStackView
)view.whc_Left(10) //view与父视图左边距10
.whc_Right(10) //view与父视图右边距10
.whc_Height(40) //view自身高度40
.whc_Top(64) //view与父视图顶边距64复制代码
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewCell.whc_CellHeightForIndexPath(indexPath, tableView: tableView)
}复制代码
什么叫隐式更新,顾名思义就是在你添加同类型约束(可能会产生冲突约束)会自动删除前面添加可能产生冲突的约束(更新约束)看下面例子:git
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView()
self.view.addSubview(view)
view.whc_Left(10) //view与父视图左边距10
.whc_Right(10) //view与父视图右边距10
.whc_HeightAuto() //view高度自动
.whc_Top(64) //view与父视图顶边距64
}复制代码
有时候程序执行的过程当中根据需求须要动态调整UI布局假如点击按钮上面view高度调整固定64代码以下:github
// 单独更新height约束
private func clickButton(sender: UIButton) {
view.whc_Height(64) // 只须要执行这一行代码便可更新view高度为64
}复制代码
上面这个代码执行作了什么事情呢?
他会检查view
高度方向是否有同类型可能冲突约束若是检查到那么会删除上面添加的HeightAuto
约束而后添加新Height
固定约束64。
默认状况固定高度约束优先级比自动高度约束高因此即便不删除上面HeightAuto
也不要紧,可是有时候会由于约束冲突程序崩溃。再好比点击按钮以下修改:swift
// 单独更新top约束
private func clickButton(sender: UIButton) {
view.whc_Top(10, toView: otherView) //viwe 顶部间隙到otherView底部为10
}复制代码
一样上面的代码执行以前会检查y方向是否有同类型约束(可能冲突的约束),显然view.whc_Top(10)
和view.whc_Top(10, toView: otherView)
确定是冲突的,因此在执行上面代码WHC_AutoLayout会先删除view
的whc_Top(10)
约束而后再添加whc_Top(10, toView: otherView)
约束。
上面解释就是隐式更新约束技术而不须要像masonry从新重写view全部约束那么麻烦。api
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView()
self.view.addSubview(view)
let label = UILabel()
self.view.addSubview(label)
label.text = "xxxxxxxxxxxxxxxxxxxxx"
label.whc_Left(10) //label左到view左边距10
.whc_Right(10) //label右到view右边距10
.whc_Top(10) //label顶到view顶边距10
.whc_HeightAuto() //label高度自动
.whc_Bottom(10, keepHeightConstraint: true) //label底到view底边距10,而且保留label高度
view.whc_Left(10) //view与父视图左边距10
.whc_Right(10) //view与父视图右边距10
.whc_Top(64) //view与父视图顶边距64
.whc_HeightAuto() //view高度自动
}复制代码
效果以下:
缓存
view
高度须要自动根据
label
高度自动调整,而
label
高度自己是自动的若是不添加
label
与
view
的底边距
whc_Bottom
关系约束
view
没法根据
label
高度变化而变化。
那可能又有人疑问?
whc_Bottom(10, keepHeightConstraint: true)
里的
keepHeightConstraint
是什么意思?前面介绍了
WHC_AutoLayout是隐式更新约束技术然而很显然
label
上
whc_HeightAuto
通常状况和
whc_Bottom
是同类型约束(冲突约束)因此这两个通常状况只能存在一个约束,可是iOS有一种特殊状况须要
Height
约束和
Bottom
约束同时存在那就是在
view
自动高度的时候(
bottom
为了撑开父视图由于父视图是自动高度因此须要一个自动高度参照约束)或者
view
底边距对齐(不采用
top
对齐)的时候如:
label.whc_Left(10) //label左到view左边距10
.whc_Right(10) //label右到view右边距10
.whc_HeightAuto() //label高度自动
.whc_Bottom(10, keepHeightConstraint: true) //label底部间隙和父视图底部10复制代码
上面label
就是一种从下往上布局。iview
从上面的例子与介绍能够咱们能够对WHC_AutoLayout得出以下结论:ide
keep
的约束API时候无论后面添加多少约束永远只会存在4个view
须要高度或者宽度自动适应时候其view
上最后一个控件须要用到5个约束(这个时候须要用到带keep
的API,一样从下或者从右开始布局有时候也须要)WHC_StackView
后面会有专门的文章详细介绍1.x方向同类型约束(不会对宽度产生影响):Left
,Leading
,Trailing
,CenterX
(包含ToView
...)
注意WHC_AutoLayout对Leading
和Trailing
特殊处理理论上他们是能够成对使用的为了统一性把他们归为同类约束Leading
左对齐Trailing
又对齐
2.y方向同类型约束(不会对宽度产生影响):Top
,BaseLineSpace
,CenterY
(包含ToView
...)
3.宽度方向同类型约束(对宽度产生影响):Width
,Right
(包含ToView
,自动宽度...)
4.高度方向同类型约束(对高度产生影响):Height
,Bottom
(包含ToView
,自动高度...)布局
WHC_AutoLayout开源地址:github.com/netyouli/WH…
本人其余优秀开源项目:github.com/netyouli/
谢谢你的耐心阅读