Search code examples
iosobjective-cswiftautolayoutvisual-format-language

Creating Spacers in VFL


AutoLayoutbyExample via Apple Developer Documentation

Anyone have an example of how to create spacer views to set the spacing between labels equal in VFL?

labelsDictionary = [ "label1": label1,
                     "label2": label2,
                     "label3": label3,
                     "label4": label4 ]

let metrics = ["edgeSpacing": 20, "spacingBetween": 5, "labelWidth": 50]
let constraints = "H:|-(==edgeSpacing)-[label1(==labelWidth@999)]-[label2(==label1)]-[label3(==label1)]-[label3(==label1)]-[label4(==label1)]-(==edgeSpacing)-|"
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat( format : constraints, 
                                                                   options : .allZeros, 
                                                                   metrics : metrics, 
                                                                     views : labelsDictionary))

I was just wondering how to create spacers in Swift to ensure that the width between the labels are always equal but of the lowest priority.

enter image description here


Solution

  • You can add 3 spacer views, which mix with the 4 labels.

    label1-spacer1-label2-spacer2-label3-spacer3-label4

    Assuming you have all 7 views inside a containerView. Because label width may change according to its text, it is good to have equal space between them.

    self.containerView.removeConstraints(containerView.constraints())
    
    let views = ["label1": label1,
        "label2": label2,
        "label3": label3,
        "label4": label4,
        "spacer1": spacer1,
        "spacer2": spacer2,
        "spacer3": spacer3
     ]
    let metrics = ["edgeSpacing": 20, "spacingBetween": 5]
    
    //make spacers have equal width, and greater than 5, make all views center align vertically
    var constH = NSLayoutConstraint.constraintsWithVisualFormat("H:|-edgeSpacing-[label1]-[spacer1(>=spacingBetween)]-[label2]-[spacer2(==spacer1)]-[label3]-[spacer3(==spacer1)]-[label4]-edgeSpacing-|", options: .AlignAllCenterY, metrics: metrics, views: views)
    view.addConstraints(constH)
    
    //configure label1 vertical alignment
    let constV = NSLayoutConstraint.constraintsWithVisualFormat("V:|-edgeSpacing-[label1]-edgeSpacing-|", options: .AlignAllCenterY, metrics: metrics, views: views)
    view.addConstraints(constV)
    
    //make spacers have equal height
    let constVForSpacer1 = NSLayoutConstraint.constraintsWithVisualFormat("V:|-edgeSpacing-[spacer1(==spacer2)]-edgeSpacing-|", options: .allZeros, metrics: metrics, views: views)
    view.addConstraints(constVForSpacer1)
    
    let constVForSpacer2 = NSLayoutConstraint.constraintsWithVisualFormat("V:|-edgeSpacing-[spacer2(==spacer3)]-edgeSpacing-|", options: .allZeros, metrics: metrics, views: views)
    view.addConstraints(constVForSpacer2)