0

I have a xib that defines a view which is a single grey rectangle. The view is added programmatically to a UIStackView, which is inside a UIScrollView. The added views show up fine until I try adding any constraint to the grey rectangle, then they all disappear. I'm not experienced with how constraints work however ANY constraint I try to add causes the grey rectangles to disappear. I'm abit new to iOS development so any pointers in the right direction appreciated.

1 Answers1

0

Maybe its just the way you are setting the constraints (maybe you could post your code?). I prefer to set the constraints with the interface builder, since I'm new to iOS development. This answer might help you.

Do you plan to have a squared UIView of width: 100 and Height: 100 centered inside the UIView of an UIViewController? If so, you may try one of the 7 following Swift 3 Auto Layout snippets:


1. NSLayoutConstraint + addConstraints(_ constraints: [NSLayoutConstraint]) style

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = UIColor.red
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerX, relatedBy:

NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0) let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0) let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100) let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100)

    view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}

2. NSLayoutConstraint + activate(_ constraints: [NSLayoutConstraint]) style Note: `activate(_ constraints:

[NSLayoutConstraint])` requires iOS 8

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = UIColor.red
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerX, relatedBy:

NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0) let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0) let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100) let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100)

    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}

3. Pure Visual Format Language style + addConstraints(_ constraints: [NSLayoutConstraint]) style

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = UIColor.red
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    let views = ["view": view, "newView": newView]
    let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat:

"H:[view]-(<=0)-[newView(100)]", options: NSLayoutFormatOptions.alignAllCenterY, metrics: nil, views: views) let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view]-(<=0)-[newView(100)]", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)

    view.addConstraints(horizontalConstraints)
    view.addConstraints(verticalConstraints)
}

4. NSLayoutConstraint + Visual Format Language + activate(_ constraints: [NSLayoutConstraint]) style Note: `activate(_

constraints: [NSLayoutConstraint])` requires iOS 8

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = UIColor.red
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerX, relatedBy:

NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0) let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)

    let views = ["newView": newView]
    let widthConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[newView(100)]",

options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views) let heightConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[newView(100)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)

    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
    NSLayoutConstraint.activate(widthConstraints)
    NSLayoutConstraint.activate(heightConstraints)
}

5. UIViewAutoresizing style Note: Springs and Struts will be translated into corresponding auto layout constraints at runtime.

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    newView.backgroundColor = UIColor.red
    newView.translatesAutoresizingMaskIntoConstraints = true
    view.addSubview(newView)

    newView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
    newView.autoresizingMask = [UIViewAutoresizing.flexibleLeftMargin,

UIViewAutoresizing.flexibleRightMargin, UIViewAutoresizing.flexibleTopMargin, UIViewAutoresizing.flexibleBottomMargin] }


6. NSLayoutAnchor + activate(_ constraints: [NSLayoutConstraint]) style Note: `activate(_ constraints:

[NSLayoutConstraint])requires iOS 8,NSLayoutAnchor` requires iOS 9

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = UIColor.red
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
    let widthConstraint = newView.widthAnchor.constraint(equalToConstant: 100)
    let heightConstraint = newView.heightAnchor.constraint(equalToConstant: 100)
    NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}

7. Subclassing + activate(_ constraints: [NSLayoutConstraint]) style Note: activate(_ constraints: [NSLayoutConstraint]) requires

iOS 8, NSLayoutAnchor requires iOS 9

import UIKit

class CustomView: UIView {

    override var intrinsicContentSize: CGSize {
        return CGSize(width: 100, height: 100)
    }

}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let newView = CustomView()
        newView.backgroundColor = UIColor.red
        newView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(newView)

        let horizontalConstraint = newView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        let verticalConstraint = newView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
    }

}

Also, check the documentation

Nathan Barreto
  • 365
  • 2
  • 21