title: UIScrollView not scrolling w/ programmatic autolayout constraints
body: <p>I am trying to understand how to use a <code>UIScrollView</code> programmatically.</p>
  
  <p>When I give my content a size that does not fit on screen though, it does not scroll.</p>
  
  <pre class="lang-swift prettyprint-override"><code>
  final class ProfileView: UIView {
  
      private var isIpad: Bool {
          return UIDevice.current.userInterfaceIdiom == .pad
      }
  
      private lazy var headerImageView: UIImageView = {
          let iv = UIImageView(frame: .zero)
          iv.translatesAutoresizingMaskIntoConstraints = false
          iv.heightAnchor.constraint(equalToConstant: 600).isActive = true
          iv.backgroundColor = .purple
          return iv
      }()
  
      private lazy var profileImageView: UIImageView = {
          let iv = UIImageView(frame: .zero)
          iv.translatesAutoresizingMaskIntoConstraints = false
          [iv.heightAnchor, iv.widthAnchor].forEach { $0.constraint(equalToConstant: 170).isActive = true }
          iv.layer.cornerRadius = 170 / 2
          iv.layer.borderColor = .white
          iv.layer.borderWidth = 3
          iv.layer.masksToBounds = true
          iv.contentMode = .scaleAspectFill
          iv.clipsToBounds = true
          iv.backgroundColor = .red
  
          return iv
      }()
  
      private(set) lazy var nameLabel: UILabel = {
          let label = UILabel(frame: .zero)
          label.translatesAutoresizingMaskIntoConstraints = false
          label.text = "Foo\nBar"
          label.numberOfLines = 2
          return label
      }()
  
      private lazy var contentScrollView: UIScrollView = {
          let sv = UIScrollView(frame: .zero)
          sv.translatesAutoresizingMaskIntoConstraints = false
          return sv
      }()
  
      override init(frame: CGRect) {
          super.init(frame: frame)
  
          configureLayout()
      }
  
      required init?(coder: NSCoder) {
          return nil
      }
  
      private func configureLayout() {
  
          addSubview(contentScrollView)
          [headerImageView, profileImageView, nameLabel].forEach { contentScrollView.addSubview($0) }
  
          let compactConstraints = [
              contentScrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
              contentScrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
              contentScrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
              contentScrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
  
              headerImageView.topAnchor.constraint(equalTo: topAnchor),
              headerImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
              headerImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
  
              profileImageView.centerYAnchor.constraint(equalTo: headerImageView.bottomAnchor),
              profileImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
  
              nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16),
              nameLabel.centerXAnchor.constraint(equalTo: profileImageView.centerXAnchor),
  
          ]
  
          NSLayoutConstraint.activate(compactConstraints)
      }
  }
  </code></pre>
  
  <p>This gives me the following -
  <a href="https://i.stack.imgur.com/N5GXQ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/N5GXQ.png" alt="enter image description here"></a></p>
  
  <p>The header image pushes the name label and avatar off screen and scrolling does not work.</p>
  
  <p>I've read a bunch about giving the scroll view a huge offset so it scrolls, but that surely cannot be correct.</p>