用多了 Masonry 、Snapkit 等第三方框架,自然体会了其中的方便之处,实际上,苹果本身也有自身的自动布局框架,这次来谈谈 NSLayoutConstraint 和 VFL 两种原生自动布局框架。当然,如果对 Masonry 感兴趣,也可直接点击传送门:浅谈 Masonry 布局框架
实际上,Masonry 就是对系统原生 NSLayoutConstraint 进行封装的第三方自动布局框架。
废话不多说,直接进入正题(采用最新的 swift3.1 讲解)
NSLayoutConstraint
public convenience init(item view1: Any,
attribute attr1: NSLayoutAttribute,
relatedBy relation: NSLayoutRelation,
toItem view2: Any?,
attribute attr2: NSLayoutAttribute,
multiplier: CGFloat,
constant c: CGFloat)
构造函数参数说明:
NSLayoutConstraint(item: 视图,
attribute: 约束属性,
relatedBy: 约束关系,
toItem: 参照视图,
attribute: 参照属性,
multiplier: 乘积,
constant: 约束数值)
如果指定 宽、高 约束,则:
1. 参照视图设置为nil;
2. 参照属性选择 .notAnAttribute 。
NSLayoutConstraint 的布局方式可以简单得总结为一个公式:
view1.attr1 = view2.attr2 * multiplier + constant
下面给出代码实例,具体功能不详细说了,比较容易懂:
addConstraints([NSLayoutConstraint(item: tipLabel,
attribute: .centerX,
relatedBy: .equal,
toItem: iconView,
attribute: .centerX,
multiplier: 1.0,
constant: 0)])
addConstraints([NSLayoutConstraint(item: tipLabel,
attribute: .top,
relatedBy: .equal,
toItem: iconView,
attribute: .bottom,
multiplier: 1.0,
constant: 20)])
addConstraints([NSLayoutConstraint(item: tipLabel,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1.0,
constant: 236)])
VFL 可视化格式语言
open class func constraints(withVisualFormat format: String,
options opts: NSLayoutFormatOptions = [],
metrics: [String : Any]?,
views: [String : Any]) -> [NSLayoutConstraint]
参数说明:
open class func constraints(withVisualFormat:VLF公式,
options :[],
metrics: 约束数值 [String:数值],
views: 视图字典 [String:子视图]
VFL 可视化格式语言简要说明:
H:水平方向
V:垂直方向
| :边界
[]:包含控件的名称字符串,对应关系在 views 字典中定义
():定义控件的宽/高,可以在 metrics 中指定
注意点:VFL 通常用于连续参照关系,如果遇到居中对齐,通常直接使用参照。
来一段示例代码:
// views:定义VFL中的控件名称和实际名称映射关系
// metrics:定义VFL中()指定的常数映射关系
let viewDict:[String:Any] = ["maskIconView":maskIconView,
"registerButton":registerButton]
let metrics = ["spacing":-20]
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[maskIconView]-0-|",
options: [],
metrics: nil,
views: viewDict))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[maskIconView]-(spacing)-[registerButton]",
options: [],
metrics: metrics,
views: viewDict))