In order to add width equals to its superview height we can do following
NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: view.superview, attribute: .height, multiplier: 1, constant: 0)
or we can do it from interface builder
But how can I do the same using VFL?
From the documentation of Auto Layout Guide: Visual Format Language
The notation prefers good visualization over completeness of
expressibility. Most of the constraints that are useful in real user
interfaces can be expressed using visual format syntax, but there are
a few that cannot. One useful constraint that cannot be expressed is a
fixed aspect ratio (for example, imageView.width = 2 *
imageView.height). To create such a constraint, you must use
constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:
.
"Width equals Height" is a ratio (to 1). So it's not possible.
I don't think you can, since that's a pretty uncommon setup. Esoteric use cases like this are where it's best to use the explicit initializer on NSLayoutConstraint.
As already mentioned, the Docs point out that you cannot set certain (common) constraints using VFL. Here's a simple example of adding just one additional line to get what you want.
You can run this in a Playground:
import UIKit
import PlaygroundSupport
class TestVC: UIViewController {
let squareView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .green
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
// add the subview
view.addSubview(squareView)
//Views to add constraints to
let views = Dictionary(dictionaryLiteral: ("sqV", squareView))
// 40 points from left, width of 100
let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-40-[sqV(==100)]", options: [], metrics: nil, views: views)
view.addConstraints(horizontalConstraints)
// 40 points from top, no height setting
let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-40-[sqV]", options: [], metrics: nil, views: views)
view.addConstraints(verticalConstraints)
// set height equal to width (1:1 ratio)
squareView.heightAnchor.constraint(equalTo: squareView.widthAnchor, multiplier: 1.0).isActive = true
}
}
let vc = TestVC()
PlaygroundPage.current.liveView = vc