My Swift 4 UIScrollView con restricciones de distribución automática no se desplaza

He creado un pequeño patio de juegos de demostración para que esto funcione antes de agregar la vista a mi aplicación.

Tengo una vista de desplazamiento que contendrá una serie de botones para desplazarse horizontalmente. Sé que estos botones deben ir a una vista de contenedor dentro de la vista de desplazamiento y también lo han creado. Inicialmente estaba usando restricciones de distribución automática para crear todo esto, pero ahora he intentado usar constantes para garantizar que la vista de contenido sea más grande que la vista de desplazamiento. Sin embargo, los botones aún no se desplazarán ... ¿me he perdido algo? ¿Las vistas de desplazamiento no funcionan con el diseño automático?

Estoy haciendo todo esto programáticamente también en mi iPad, por lo que desafortunadamente las soluciones con el generador de interfaces no son una opción ...

Aquí está el código completo:

import UIKit
import PlaygroundSupport

class FilterViewController: UIViewController {
    var filterView: UIView!
    var scrollView: UIScrollView!
    var containerView: UIView!

    override func loadView() {
        filterView = UIView()
        view = filterView
        view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)

        scrollView = UIScrollView()
        scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.topAnchor.constraint(equalTo:view.topAnchor, constant:40).isActive = true
        scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
        scrollView.widthAnchor.constraint(equalTo:view.widthAnchor).isActive = true
        scrollView.heightAnchor.constraint(equalToConstant: 200).isActive = true
        scrollView.isScrollEnabled = true

        containerView = UIView()
        containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
        scrollView.addSubview(containerView)
        containerView.frame = CGRect(x: 0, y: 0, width: 1080, height: 200)
    }

    class Buttons{
        let button = UIButton()
        init (titleText : String){
            button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
            button.setTitle(titleText, for: .normal)
            button.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let b1 = Buttons(titleText: "one")
        let b2 = Buttons(titleText: "two")
        let b3 = Buttons(titleText: "three")
        let b4 = Buttons(titleText: "four")
        let b5 = Buttons(titleText: "five")
        let buttonArray = [b1,b2,b3,b4,b5]
        var startPoint : CGFloat = 0.0
        for btn in buttonArray {
            let theBtn = btn.button
            containerView.addSubview(theBtn)
            theBtn.frame = CGRect(x: startPoint, y: 0, width: 200, height: 200)
            startPoint += 220
        }

    }
}

let filterViewController = FilterViewController()
PlaygroundPage.current.liveView = filterViewController

Gracias vacawama! Aquí está el mini proyecto completo (trabajando ahora) con todas las restricciones de diseño automático:

import UIKit
import PlaygroundSupport

class FilterViewController: UIViewController {
    var filterView: UIView!
    var scrollView: UIScrollView!
    var containerView: UIView!

    override func loadView() {
        filterView = UIView()
        view = filterView
        view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)

        scrollView = UIScrollView()
        scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.topAnchor.constraint(equalTo:view.topAnchor, constant:40).isActive = true
        scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
        scrollView.widthAnchor.constraint(equalTo:view.widthAnchor).isActive = true
        scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25).isActive = true
        scrollView.isScrollEnabled = true

        containerView = UIView()
        containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
        scrollView.addSubview(containerView)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.topAnchor.constraint(equalTo:scrollView.topAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo:scrollView.leadingAnchor).isActive = true
        containerView.trailingAnchor.constraint(equalTo:scrollView.trailingAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo:scrollView.bottomAnchor).isActive = true
        containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true



    }

    class Buttons{
        let button = UIButton()
        init (titleText : String){
            button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
            button.setTitle(titleText, for: .normal)
            //button.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let b1 = Buttons(titleText: "one")
        let b2 = Buttons(titleText: "two")
        let b3 = Buttons(titleText: "three")
        let b4 = Buttons(titleText: "four")
        let b5 = Buttons(titleText: "five")
        let buttonArray = [b1,b2,b3,b4,b5]
        var startPoint = containerView.leadingAnchor
        for btn in buttonArray {
            let theBtn = btn.button
            containerView.addSubview(theBtn)
            theBtn.translatesAutoresizingMaskIntoConstraints = false
            theBtn.leadingAnchor.constraint(equalTo:startPoint, constant:20).isActive = true
            theBtn.topAnchor.constraint(equalTo:containerView.topAnchor).isActive = true
            theBtn.bottomAnchor.constraint(equalTo:containerView.bottomAnchor).isActive = true
            theBtn.widthAnchor.constraint(equalTo: theBtn.heightAnchor).isActive = true
            startPoint = theBtn.trailingAnchor
            containerView.widthAnchor.constraint(equalTo: theBtn.widthAnchor, multiplier:CGFloat(buttonArray.count), constant: CGFloat(buttonArray.count * 20)).isActive = true
        }
    }
}

let filterViewController = FilterViewController()
PlaygroundPage.current.liveView = filterViewController

Respuestas a la pregunta(1)

Su respuesta a la pregunta