在使用Autolayout进行视图布局时,NSLayoutConstraint对象是非常常用的,我们知道NSLayoutConstraint对象的创建需要很多的参数,而且在对一个视图进行自动布局时,通常需要创建大量的NSLayoutConstraint对象,这是非常烦琐且不直观的。为了解决这种尴尬的情况,Apple开发了一种新的描述语言VFL(VisualFormat Language,可视化格式语言),用来帮助开发者可视化的、快速的创建约束对象。
VFL使用字符串来描述组件间的约束关系,之后由解析引擎生成一组真实的NSLayoutConstraint约束对象。
在VFL语言中,首先需要指明布局的方向,即是水平方向的布局还是竖直方向的布局,水平方向使用“H:”表示,竖直方向使用“V:”表示。另外,使用“-”表示组件间的间距,使用“|”表示组件的边界。下面的代码演示了如何使用VFL进行约束对象的创建:
self.view.translatesAutoresizingMaskIntoConstraints = false let v1 = UIView() v1.backgroundColor = UIColor.red let v2 = UIView() v2.backgroundColor = UIColor.blue let v3 = UIView() v3.backgroundColor = UIColor.green v1.translatesAutoresizingMaskIntoConstraints = false; v2.translatesAutoresizingMaskIntoConstraints = false; v3.translatesAutoresizingMaskIntoConstraints = false; self.view.addSubview(v1) elf.view.addSubview(v2) self.view.addSubview(v3) // 使用VFL创建约束对象 let hArray = NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[v1]-10-[v2(==v1)]-10-[v3(==v2)]-10-|", options: [.alignAllTop, .alignAllBottom], metrics: nil, views: ["v1":v1, "v2":v2, "v3":v3]) let vArray = NSLayoutConstraint.constraints(withVisualFormat: "V:|-100-[v1(100@1000)]", metrics: nil, views: ["v1":v1]) NSLayoutConstraint.activate(hArray) NSLayoutConstraint.activate(vArray)
上面的v1、v2、v3都是视图代号,在其后的小括号中可以对视图的宽度/高度和约束优先级进行设置。运行代码,布局效果如图所示。
布局效果
在上面的代码中,constraints类方法用来将VFL字符串解析成约束对象,这个方法的完整定义如下:
open class func constraints(withVisualFormat format: String, options opts: NSLayoutConstraint.FormatOptions = [], metrics: [String : Any]?, views: [String : Any]) -> [NSLayoutConstraint]
在上面的方法中,参数format为VFL语言的字符串,opts参数用来设置视图的对齐方式,metrics参数用来指定变量列表,如果VFL中有使用到变量作为约束值,则需要在metrics字典中进行指定,views用来指定视图列表。例如,VFL字符串中使用的间距10是某个变量提供的,则可以改写如下:
let spec = 10; let hArray = NSLayoutConstraint.constraints(withVisualFormat: "H:|-spec-[v1]-spec-[v2(==v1)]-spec-[v3(==v2)]-spec-|", options: [.alignAllTop, .alignAllBottom], metrics: ["spec": spec], views: ["v1":v1, "v2":v2, "v3":v3])
在使用VFL生成约束对象时,还有一点需要注意,constraints类方法的opts参数用来指定布局次轴方向上的视图对齐方式。次轴方向是指与布局方向垂直的方向:对于水平方向的布局,次轴方向就是竖直方向;对于竖直方向,次轴方向就是水平方向。
VFL虽然写着简单,但并不是万能的,当视图间的关系需要以比例的方式进行约束时,VFL就无能为力了。其实在实际开发中VFL使用的并不多,对于自动布局,更多的是借助成熟的第三方库来创建约束。但是对VFL的熟悉与理解依然十分重要,当因为布局冲突产生运行时问题时,控制台会打印相关的约束对象,打印时就会将布局的信息以VFL字符串的方式输出,熟悉它可以帮助我们更好地发现布局问题。