I am trying to perform the following task that is shown with the following image
This is what I have as far as constraints go so far, the "Entertainment" string is represented by the categoryLabel and the "Disney: build it frozen" by nameLabel.
addConstraints(withFormat: "H:|-8-[v0(90)]-8-[v1]-8-|", views: imageView, nameLabel)
addConstraints(withFormat: "V:|-8-[v0(90)]", views: imageView)
addConstraints(withFormat: "H:[v0]-8-[v1]", views: imageView, nameLabel)
addConstraints(withFormat: "V:|-8-[v0]-8-[v1]", views: nameLabel, categoryLabel)
func addConstraints(withFormat format: String, views: UIView...) {
var viewsDictionary = [String: UIView]()
for (index, view) in views.enumerated() {
let key = "v\(index)"
view.translatesAutoresizingMaskIntoConstraints = false
viewsDictionary[key] = view
}
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
The problem I am having is how to add the "categorylabel" to the constraints such that it is aligned to right of the imageView by 8 pixels and directly under the nameLabel by 8 pixels. As you can see from the screenshot I can achieve placing it below the nameLabel but I am having a hard time making it such that the "categorylabel" is to the right of the image view as well.
Any tips would be very much appreciated :)
Unfortunately by wrapping NSLayoutConstraint.constraints
in your own function, you have prevented access to the feature you need, which is to specify the .alignAllLeading
NSLayoutFormatOptions
to your nameLabel-category constraint.
Essentially, what you need is:
NSLayoutConstraint.constraints(withVisualFormat: "V:|-8-[v0]-8-[v1]", options: .alignAllLeading, metrics: nil, views: viewsDictionary))
This will tell autolayout that you want the leading edges of the two items to be aligned and separated vertically by 8. Since you already have your name field positioned relative to the edge of the image view, this will put your category field where you want it.
You can re-factor your addConstraints
function to accept NSLayoutFormatOptions:
func addConstraints(withFormat format: String, options: NSLayoutFormatOptions = NSLayoutFormatOptions(), views: UIView...) {
var viewsDictionary = [String: UIView]()
for (index, view) in views.enumerated() {
let key = "v\(index)"
view.translatesAutoresizingMaskIntoConstraints = false
viewsDictionary[key] = view
}
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: options, metrics: nil, views: viewsDictionary))
}
and then call it:
addConstraints(withFormat: "V:|-8-[v0]-8-[v1]", options: .alignAllLeading, views: nameLabel, categoryLabel)
By the way, you don't need to use storyboards to use stack views.