0

I want to get the following structure programmatically (and am currently failing...):

  • View
    • Scroll View
      • Vertical Stack View

I was able to get what I wanted in Interface Builder, but cannot seem to figure out how to achieve this in code. In IB, it looks like this (please click on the picture to see it fully):

enter image description here

The settings of the stack view look like this:

enter image description here

Now, this is my attempt to mirror that in code:

import UIKit

class ScrollViewController: UIViewController {

    lazy var scrollView: UIScrollView = {
        let s = UIScrollView()
        s.contentMode = .scaleToFill
        s.backgroundColor = .gray
        s.accessibilityIdentifier = "scroll_view"
        s.translatesAutoresizingMaskIntoConstraints = false
        return s
    }()

    lazy var stackView: UIStackView = {
        let s = UIStackView()
        s.axis = .vertical
        s.alignment = .fill
        s.distribution = .equalSpacing
        s.spacing = 10
        s.contentMode = .scaleToFill
        s.accessibilityIdentifier = "stack_view"
        return s
    }()

    // See helper method at bottom
    lazy var textField1 = self.createTextField(placeholder: "Textfield 1")
    lazy var textField2 = self.createTextField(placeholder: "Textfield 2")
    lazy var textField3 = self.createTextField(placeholder: "Textfield 3")
    lazy var textField4 = self.createTextField(placeholder: "Textfield 4")
    lazy var textField5 = self.createTextField(placeholder: "Textfield 5")
    lazy var textField6 = self.createTextField(placeholder: "Textfield 6")

    override func loadView() {
        view = UIView()
        view.backgroundColor = .white

        view.addSubview(scrollView)
        scrollView.addSubview(stackView)

        stackView.addArrangedSubview(textField1)
        stackView.addArrangedSubview(textField2)
        stackView.addArrangedSubview(textField3)
        stackView.addArrangedSubview(textField4)
        stackView.addArrangedSubview(textField5)
        stackView.addArrangedSubview(textField6)

        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20),
            scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),

            stackView.widthAnchor.constraint(equalTo: scrollView.contentLayoutGuide.widthAnchor),
            stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
            stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
            stackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor)
        ])
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        scrollView.contentSize = stackView.frame.size
    }

    func createTextField(placeholder: String) -> UITextField {
        let t = UITextField()
        t.translatesAutoresizingMaskIntoConstraints = false
        t.borderStyle = .roundedRect
        t.clearButtonMode = .whileEditing
        t.text = placeholder
        t.placeholder = placeholder
        t.accessibilityIdentifier = placeholder
        return t
    }
}

I am quite obviously missing something, but even after spending several hours of trying and googling, I still haven't found a solution...

What I do realize is that all the text fields' and the stack view's frames are (0, 0, 0, 0), so quite obviously, I am missing some constraints, right?

Rashed Hasan
  • 3,721
  • 11
  • 40
  • 82
appfrosch
  • 1,146
  • 13
  • 36
  • for `stackView`, you are not defining `stackView.translatesAutoresizingMaskIntoConstraints = false` – Kishan Bhatiya Feb 16 '20 at 09:13
  • This SO post has all the details: https://stackoverflow.com/questions/31668970/is-it-possible-for-uistackview-to-scroll. Not sure what you are creating or what problem you are trying to solve... But a UITableView might be better suited for what you are working on. – Eelco Koelewijn Feb 16 '20 at 12:25
  • @KishanBhatiya oh boy, how stupid can I be – thanks for pointing that out... It of course works when I set the `translatesAutoresizingMaskIntoConstraints` property to false... – appfrosch Feb 16 '20 at 18:49
  • @EelcoKoelewijn thanks a lot for that input, didn't find that one in my searches... Will take a closer look at that to better understand that more. My specific problem in this case was that I did not set `translatesAutoresizingMaskIntoConstraints`... – appfrosch Feb 16 '20 at 18:57

1 Answers1

0

for stackView, you are not defining stackView.translatesAutoresizingMaskIntoConstraints = false

Kishan Bhatiya
  • 2,175
  • 8
  • 14