Search code examples
iosswiftvisual-format-language

How to use VLF to stack objects one on top of the other?


For some reason this VLF code.. :

    // Label Constraints
    var allConstraints = [NSLayoutConstraint]()
    let views = ["chapterVerseLabel" : chapterVerseLabel, "sanskritLabel" : sanskritLabel, "englishLabel" : englishLabel, "translationLabel" : translationLabel, "commentaryLabel" : commentaryLabel]
    allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("V:|-[chapterVerseLabel]-[sanskritLabel]-[englishLabel]-[translationLabel]-[commentaryLabel]-|", options: [], metrics: nil, views: views)
    allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[chapterVerseLabel]-15-|", options: [], metrics: nil, views: views)
    allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[sanskritLabel]-15-|", options: [], metrics: nil, views: views)
    allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[englishLabel]-15-|", options: [], metrics: nil, views: views)
    allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[translationLabel]-15-|", options: [], metrics: nil, views: views)
    allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[commentaryLabel]-15-|", options: [], metrics: nil, views: views)
    NSLayoutConstraint.activateConstraints(allConstraints)

Is producing this :

enter image description here

What I can't seem to understand is why there's an enormous gap in between the first object chapterVerseLabel . Ideally, I want the objects to be stacked on on top of the other. Maybe a 10pt margin between. Which is what I assumed this line would do :

allConstraints += NSLayoutConstraint.constraintsWithVisualFormat("V:|-[chapterVerseLabel]-[sanskritLabel]-[englishLabel]-[translationLabel]-[commentaryLabel]-|", options: [], metrics: nil, views: views)

I tried variations by adding specified heights, etc. too, but none seemed to work.


Solution

  • As all your views are vertically anchored, auto-layout has to relax at least one constraint in order to display them in relation to your device size. It doesn't know that for you is better to leave more gap at the bottom, so you have to specify it. Try assigning a lower priority to the constraint which attaches the last UILabel to the bottom of your view controller. Here's an example which specifies a priority:

    NSDictionary *metrics = @{@"lowPriority":@(UILayoutPriorityDefaultLow)};
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-30.0@lowPriority-[label]" options:0 metrics:metrics views:views];