title: NSLayoutConstraint height is not working
body: <p>I have defined a view to be a pop-up on an iOS screen using programmed constraints.</p>
  
  <pre><code>    let stopTimer = StoppageTimer(frame: CGRect.zero)
  </code></pre>
  
  <p>The view itself contains a stack view, plus a couple of buttons. When I try to set constraints for my view (from its superview - a View Controller), all of them are applied correctly except the height of my view. The code that sets these constraints is (the offending set are the last four, just before <code>view.layoutIfNeeded()</code></p>
  
  <pre><code>func setConstraints() {
      // Remove all constraints within the UIView
      view.constraints.forEach {constraint in constraint.isActive = false}
      lblNetScore.translatesAutoresizingMaskIntoConstraints = false
      lblMatchName.translatesAutoresizingMaskIntoConstraints = false
      butUnwind.translatesAutoresizingMaskIntoConstraints = false
      butMatchStats.translatesAutoresizingMaskIntoConstraints = false
      GSButtons.translatesAutoresizingMaskIntoConstraints = false
      GAButtons.translatesAutoresizingMaskIntoConstraints = false
      sb.translatesAutoresizingMaskIntoConstraints = false
      timer.translatesAutoresizingMaskIntoConstraints = false
      butSwitch.translatesAutoresizingMaskIntoConstraints = false
      Qtr.translatesAutoresizingMaskIntoConstraints = false
      butStart.translatesAutoresizingMaskIntoConstraints = false
      stopTimer.translatesAutoresizingMaskIntoConstraints = false
      // Top Line
      NSLayoutConstraint(item: butUnwind,     attribute: .leading,  relatedBy: .equal, toItem: view, attribute: .leading,    multiplier: 1, constant:  15).isActive = true
      NSLayoutConstraint(item: butUnwind,     attribute: .top,      relatedBy: .equal, toItem: view, attribute: .topMargin,  multiplier: 1, constant:   0).isActive = true
      NSLayoutConstraint(item: lblNetScore,   attribute: .centerX,  relatedBy: .equal, toItem: view, attribute: .centerX,    multiplier: 1, constant:   0).isActive = true
      NSLayoutConstraint(item: lblNetScore,   attribute: .top,      relatedBy: .equal, toItem: view, attribute: .topMargin,  multiplier: 1, constant:   0).isActive = true
      NSLayoutConstraint(item: butMatchStats, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing,   multiplier: 1, constant: -15).isActive = true
      NSLayoutConstraint(item: butMatchStats, attribute: .top,      relatedBy: .equal, toItem: view, attribute: .topMargin,  multiplier: 1, constant:   0).isActive = true
      NSLayoutConstraint(item: lblMatchName,  attribute: .top,      relatedBy: .equal, toItem: lblNetScore, attribute: .bottom,   multiplier: 1, constant: 5).isActive = true
      NSLayoutConstraint(item: lblMatchName,  attribute: .centerX,  relatedBy: .equal, toItem: view, attribute: .centerX,  multiplier: 1, constant:   0).isActive = true
      // Timer
      NSLayoutConstraint(item: timer, attribute: .top,      relatedBy: .equal, toItem: lblMatchName, attribute: .bottom,  multiplier: 1, constant: 5).isActive = true
      NSLayoutConstraint(item: timer, attribute: .centerX,  relatedBy: .equal, toItem: view,         attribute: .centerX, multiplier: 1, constant: 0).isActive = true
  
      NSLayoutConstraint(item: Qtr,   attribute: .top,      relatedBy: .equal, toItem: lblMatchName, attribute: .bottom,  multiplier: 1, constant: 5).isActive = true
      NSLayoutConstraint(item: Qtr, attribute: .leading,    relatedBy: .equal, toItem: view,         attribute: .leadingMargin, multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: Qtr, attribute: .height,     relatedBy: .equal, toItem: timer,         attribute: .height, multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: butStart,   attribute: .top, relatedBy: .equal, toItem: lblMatchName, attribute: .bottom,  multiplier: 1, constant: 5).isActive = true
      NSLayoutConstraint(item: butStart, attribute: .trailing,    relatedBy: .equal, toItem: view,   attribute: .trailingMargin, multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: butStart, attribute: .height,     relatedBy: .equal, toItem: timer,   attribute: .height, multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: butStart, attribute: .width,     relatedBy: .equal, toItem: nil,      attribute: .notAnAttribute, multiplier: 1, constant: 70).isActive = true
  
  
      // Switch Button
      NSLayoutConstraint(item: butSwitch, attribute: .top,      relatedBy: .equal, toItem: timer, attribute: .bottom,  multiplier: 1, constant: 5).isActive = true
      NSLayoutConstraint(item: butSwitch, attribute: .centerX,  relatedBy: .equal, toItem: view,  attribute: .centerX, multiplier: 1, constant: 0).isActive = true
      // ScoreBoard
      NSLayoutConstraint(item: sb, attribute: .top,      relatedBy: .equal, toItem: butSwitch, attribute: .bottom,  multiplier: 1, constant: 5).isActive = true
      NSLayoutConstraint(item: sb, attribute: .centerX,  relatedBy: .equal, toItem: view,      attribute: .centerX, multiplier: 1, constant: 0).isActive = true
      //Scoring buttons - GS
      NSLayoutConstraint(item: GSButtons, attribute: .top,      relatedBy: .equal, toItem: sb,   attribute: .bottom,        multiplier: 1, constant:   7).isActive = true
      NSLayoutConstraint(item: GSButtons, attribute: .height,   relatedBy: .equal, toItem: sb,   attribute: .height,        multiplier: 1, constant:  15).isActive = true
      NSLayoutConstraint(item: GSButtons, attribute: .leading,  relatedBy: .equal, toItem: view, attribute: .leadingMargin, multiplier: 1, constant:   0).isActive = true
      NSLayoutConstraint(item: GSButtons, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailingMargin,multiplier: 1, constant:   0).isActive = true
      // Scoring buttons - GA
      NSLayoutConstraint(item: GAButtons, attribute: .top,      relatedBy: .equal, toItem: GSButtons, attribute: .bottom,         multiplier: 1, constant:   7).isActive = true
      NSLayoutConstraint(item: GAButtons, attribute: .height,   relatedBy: .equal, toItem: sb,        attribute: .height,         multiplier: 1, constant:  15).isActive = true
      NSLayoutConstraint(item: GAButtons, attribute: .leading,  relatedBy: .equal, toItem: view,      attribute: .leadingMargin,  multiplier: 1, constant:   0).isActive = true
      NSLayoutConstraint(item: GAButtons, attribute: .trailing, relatedBy: .equal, toItem: view,      attribute: .trailingMargin, multiplier: 1, constant:   0).isActive = true
      // Stoppage Timer
      NSLayoutConstraint(item: stopTimer, attribute: .top,      relatedBy: .equal, toItem: butSwitch, attribute: .bottom,         multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: stopTimer, attribute: .height,   relatedBy: .equal, toItem: nil,       attribute: .notAnAttribute, multiplier: 1, constant: 100).isActive = true
      NSLayoutConstraint(item: stopTimer, attribute: .leading,  relatedBy: .equal, toItem: view,      attribute: .leadingMargin,  multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: stopTimer, attribute: .trailing, relatedBy: .equal, toItem: view,      attribute: .trailingMargin, multiplier: 1, constant: 0).isActive = true
      view.layoutIfNeeded()
  }
  </code></pre>
  
  <p>So the view is positioned below another button, and top/leading/trailing constraints are perfect, but the height is just ignored (no constraint errors in the debug window). When I look at the height value in debug it tells me that it's zero</p>
  
  <pre><code>(lldb) po stopTimer.frame
  ▿ (16.0, 186.5, 343.0, 0.0)
    ▿ origin : (16.0, 186.5)
      - x : 16.0
      - y : 186.5
    ▿ size : (343.0, 0.0)
      - width : 343.0
      - height : 0.0
  </code></pre>
  
  <p>I declare the view up-front using <code>CGRect.zero</code> because my constraints will re-size later.</p>
  
  <p>If I set the height to be equal to another view it works fine, but it just won't set it to be a constant height. The same thing happens with the width constraint if I try to use that in a similar way.</p>
  
  <p>Any help on solving this mystery would be appreciated.</p>
  
  <p>EDIT</p>
  
  <p>When the stopTimer view appears (I set .isHidden = false), the controls within the subview (buttons, stack view etc.) are all shown on screen, but are inaccessible (I cannot touch on them) because they are not within the bounds of the view. Apologies for verbosity, but here is the stopTimer class definition</p>
  
  <pre><code>class StoppageTimer: UIView {
  
  lazy var StoppageType: UISegmentedControl = {
      let s = UISegmentedControl(frame: CGRect.zero)
      s.insertSegment(withTitle: "Umpire Time", at: 0, animated: false)
      s.insertSegment(withTitle: "Injury Time", at: 1, animated: false)
      s.translatesAutoresizingMaskIntoConstraints = false
      s.backgroundColor = Style.backgroundColor
      s.tintColor = Style.buttonBackgroundColorA
      return s
  }()
  
  lazy var StoppageTimer: UIStackView = {
      let s = UIStackView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
      s.axis = .horizontal
      s.distribution = .fill
      s.alignment = .fill
      s.translatesAutoresizingMaskIntoConstraints = false
      return s
  }()
  
  let bgView: UIView = {
      let v = UIView()
      v.backgroundColor = Style.labelBackgroundColorA
      v.layer.cornerRadius = CGFloat(Style.buttonCornerRadius)
      v.layer.borderWidth = 3
      v.layer.borderColor = Style.buttonBackgroundColorA.cgColor
      v.translatesAutoresizingMaskIntoConstraints = false
      return v
  }()
  
  let minutes: UILabel = {
      let l = UILabel()
      l.text = "00"
      l.textAlignment = .right
      l.backgroundColor = UIColor.clear
      l.textColor = Style.labelTextColor
      l.font = UIFont.systemFont(ofSize: 40.0, weight: .thin)
      l.translatesAutoresizingMaskIntoConstraints = false
      return l
  }()
  
  let Separator: UILabel = {
      let l = UILabel()
      l.text = ":"
      l.textAlignment = .center
      l.backgroundColor = UIColor.clear
      l.textColor = Style.labelTextColor
      l.font = UIFont.systemFont(ofSize: 40.0, weight: .ultraLight)
      l.translatesAutoresizingMaskIntoConstraints = false
      return l
  }()
  
  let seconds: UILabel = {
      let l = UILabel()
      l.text = "00"
      l.textAlignment = .left
      l.backgroundColor = UIColor.clear
      l.textColor = Style.labelTextColor
      l.font = UIFont.systemFont(ofSize: 40.0, weight: .thin)
      l.translatesAutoresizingMaskIntoConstraints = false
      return l
  }()
  
  let butCont: UIButton = {
      let b = UIButton()
      b.setTitle("Continue", for: .normal)
      b.setTitleColor(Style.buttonTextColor, for: .normal)
      b.titleLabel?.font = UIFont.systemFont(ofSize: 25)
      b.titleLabel?.adjustsFontSizeToFitWidth = true
      b.showsTouchWhenHighlighted = true
      b.translatesAutoresizingMaskIntoConstraints = false
      b.backgroundColor = Style.buttonBackgroundColorB
      b.layer.cornerRadius = CGFloat(Style.buttonCornerRadius)
      b.layer.borderWidth = CGFloat(Style.buttonBorderWidth)
      return b
  }()
  
  override init(frame: CGRect) {
      super.init(frame: frame)
      addStoppageTimer()
  }
  
  required init(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
  }
  
  override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
      setStoppageTimerConstraints()
  }
  
  func addStoppageTimer() {
      StoppageTimer.arrangedSubviews.forEach { subview in subview.removeFromSuperview() }
      addSubview(bgView)
      StoppageTimer.addArrangedSubview(minutes)
      StoppageTimer.addArrangedSubview(Separator)
      StoppageTimer.addArrangedSubview(seconds)
      addSubview(StoppageTimer)
      addSubview(StoppageType)
      addSubview(butCont)
  }
  
  func setStoppageTimerConstraints() {
      constraints.forEach { constraint in constraint.isActive = false }
      translatesAutoresizingMaskIntoConstraints = false
  
      NSLayoutConstraint(item: bgView, attribute: .top,      relatedBy: .equal, toItem: self, attribute: .top,      multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: bgView, attribute: .bottom,   relatedBy: .equal, toItem: self, attribute: .bottom,   multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: bgView, attribute: .leading,  relatedBy: .equal, toItem: self, attribute: .leading,  multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: bgView, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
  
      NSLayoutConstraint(item: StoppageType, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 10).isActive = true
      NSLayoutConstraint(item: StoppageType, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1, constant: 20).isActive = true
      NSLayoutConstraint(item: StoppageType, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1, constant: -20).isActive = true
  
      NSLayoutConstraint(item: StoppageTimer, attribute: .top,      relatedBy: .equal, toItem: StoppageType, attribute: .bottom,          multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: StoppageTimer, attribute: .centerX,   relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: StoppageTimer, attribute: .width,  relatedBy: .equal, toItem: nil, attribute: .notAnAttribute,      multiplier: 1, constant: 150).isActive = true
  
      NSLayoutConstraint(item: butCont, attribute: .centerX, relatedBy: .equal, toItem: bgView, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
      NSLayoutConstraint(item: butCont, attribute: .top, relatedBy: .equal, toItem: StoppageTimer, attribute: .bottom, multiplier: 1, constant: 5).isActive = true
  
      minutes.widthAnchor.constraint(equalToConstant: 60).isActive = true
      seconds.widthAnchor.constraint(equalToConstant: 60).isActive = true
  
  
      layoutIfNeeded()
  }
  </code></pre>
  
  <p>I cannot see any reason why all other constraints would work perfectly (even height does provided it refers to the height of another view, and is not just a constant value), but height and width are just ignored when defined as a constant. Debug log is totally silent, it does not object to any constraints.</p>
  
  <p>I also notice that when debugging, the height constraint is set as it executes the height constraint line, but looking at the constraints after <code>view.layoutIfNeeded()</code> the height constraint is no more...</p>
  
  <pre><code>(lldb) po stopTimer.constraints
  ▿ 1 element
    - 0 : &lt;NSLayoutConstraint:0x6000000997d0 NetScore.StoppageTimer:0x7fc3bff223d0.height == 100   (active)&gt;
  
  (lldb) po stopTimer.constraints
  ▿ 11 elements
    - 0 : &lt;NSLayoutConstraint:0x60c00009d6f0 V:|-(0)-[UIView:0x7fc3bff225f0]   (active, names: '|':NetScore.StoppageTimer:0x7fc3bff223d0 )&gt;
    - 1 : &lt;NSLayoutConstraint:0x60c000281090 UIView:0x7fc3bff225f0.bottom == NetScore.StoppageTimer:0x7fc3bff223d0.bottom   (active)&gt;
    - 2 : &lt;NSLayoutConstraint:0x60c0002810e0 H:|-(0)-[UIView:0x7fc3bff225f0]   (active, names: '|':NetScore.StoppageTimer:0x7fc3bff223d0 )&gt;
    - 3 : &lt;NSLayoutConstraint:0x60c000281130 UIView:0x7fc3bff225f0.trailing == NetScore.StoppageTimer:0x7fc3bff223d0.trailing   (active)&gt;
    - 4 : &lt;NSLayoutConstraint:0x60c000281180 V:|-(10)-[UISegmentedControl:0x7fc3bff23f10]   (active, names: '|':NetScore.StoppageTimer:0x7fc3bff223d0 )&gt;
    - 5 : &lt;NSLayoutConstraint:0x60c0002811d0 H:|-(20)-[UISegmentedControl:0x7fc3bff23f10]   (active, names: '|':NetScore.StoppageTimer:0x7fc3bff223d0 )&gt;
    - 6 : &lt;NSLayoutConstraint:0x60c000281220 UISegmentedControl:0x7fc3bff23f10.trailing == NetScore.StoppageTimer:0x7fc3bff223d0.trailing - 20   (active)&gt;
    - 7 : &lt;NSLayoutConstraint:0x60c0002812c0 V:[UISegmentedControl:0x7fc3bff23f10]-(0)-[UIStackView:0x7fc3bff23d00]   (active)&gt;
    - 8 : &lt;NSLayoutConstraint:0x60c000281310 UIStackView:0x7fc3bff23d00.centerX == NetScore.StoppageTimer:0x7fc3bff223d0.centerX   (active)&gt;
    - 9 : &lt;NSLayoutConstraint:0x60c00009f360 UIButton:0x7fc3bff23080'Continue'.centerX == UIView:0x7fc3bff225f0.centerX   (active)&gt;
    - 10 : &lt;NSLayoutConstraint:0x60c0002813b0 V:[UIStackView:0x7fc3bff23d00]-(5)-[UIButton:0x7fc3bff23080'Continue']   (active)&gt;
  </code></pre>