title: UIScrollView overlaps other UIElements so they are not clickable anymore
body: <p>Dear StackOverflowCommunity,</p>
  
  <p>im currently working on a project, where I need to make a fully dynamic user interface.
  For that, im building all of it programatically to make it as easy as possible.
  I've now come to a problem which is as soon as I wrap my contentView(UIStackView) with an UIScrollView to make it scrollable, the scrollView is in front of all the other UIElements so that I can only scroll. I can not interact with Buttons, Sliders, Switches or anything, no event will get triggered.</p>
  
  <p>I've literally done anything I could think of (working on that Problem for DAYS) but couldn't find any suiting answer whether on google directly nor on stack overflow or apple forums.</p>
  
  <p>I'm pretty sure its a pretty small change that I just wasn't capable of thinking of. I really appreciate any of your help.</p>
  
  <p>Structure is like this: 
  <code>ViewController &gt; UIScrollView &gt; UIStackView &gt; Item Wrappers (for example contains a UISwitch and a Describing Label) &gt; Single UIElement</code></p>
  
  <p>On User Interaction (for example choosing a different mode) the wrappers get removed and/or added to the view as the user needs.
  I did only post the code that is somehow relevant for this problem (in my opinion). If you need any further information feel free to ask.</p>
  
  <p>I maybe need to add:
  As soon as I remove the UIScrollView and just add the StackView (named contentView in code) to the main view it all works just fine, I just can't scroll it which is a big problem as soon as I have more than like 5 element wrappers attached to the view.</p>
  
  <pre><code>    var wrappers : Dictionary&lt;String, UIView&gt; = [:]
  var elements : Dictionary&lt;String, [UIView]&gt; = [:]
  var constraints : Dictionary = [String: [[NSLayoutConstraint]]]()
  let contentView = UIStackView()
  
  let states = [
      "state_operating_hours",
      "state_dim",
      "state_brightness_sensor",
      "state_operating_voltage",
      "state_circuit_voltage",
      "state_load_current_led",
      "state_output_power",
      "state_temperature",
      "state_error",
      "state_sw_version",
      "state_hw_version"
  ]
  
  let checkboxes = [
      "summertime_wintertime",
      "dali",
      "error_output"
  ]
  
  let sliders = [
      "immediate_sensitivity",
      "immediate_dawn",
      "immediate_dim",
      "immediate_day",
      "immediate_dusk",
      "immediate_night",
      "aging"
  ]
  
  let textInputs = [
      "module_name",
      "switch_delay"
  ]
  
  let dropdowns = [
      "mode",
      "bt_state",
      "config_output"
  ]
  
  let timePickers = [
      "phase_0",
      "phase_1",
      "phase_2",
      "phase_3"
  ]
  
  let buttons = [
      "state_trigger",
      "reset_trigger",
  ]
  
  let l_kind_criteria = [
      "immediate_dawn",
      "immediate_day",
      "immediate_dusk",
      "immediate_night",
      "immediate_sensitivity"
  ]
  
  let d_kind_criteria = [
      "immediate_dim"
  ]
  
  let t_kind_criteria = [
      "phase_0",
      "phase_1",
      "phase_2",
      "phase_3"
  ]
  
  let m_kind_criteria = [
      "immediate_dawn",
      "immediate_day",
      "immediate_dusk",
      "immediate_night",
      "immediate_sensitivity",
      "phase_0",
      "phase_1"
  ]
  
  let user_criteria = [
      //"access",
      //"state_trigger",
      //"reset_trigger",
      "mode",
      "summertime_wintertime"
  ]
  
  let service_criteria = [
      "module_name",
      //"access",
      "state_trigger",
      "reset_trigger",
      "mode",
      "bt_state",
      "config_output",
      "aging",
      "switch_delay",
      "summertime_wintertime",
      "error_output",
      "dali"
  ]
  
  override func viewDidLoad() {
      bleService.delegate = self
      bleService.requestAuthMode()
      view.backgroundColor = .lightGray
      bleService.send(aText: "c28r:#")
      bleService.send(aText: "c05r:#")
      Toast.show(message: "Statuswerte werden abgerufen..." , controller: self)
      buildLayout()
  }
  
  // Class - Functions
  
  func buildLayout() {
      // Building the Basic Layout
  
      let topView = UIView()
      topView.backgroundColor = .purple
      self.view.addSubview(topView)
      topView.translatesAutoresizingMaskIntoConstraints = false
  
      let logoImageView = UIImageView(image: UIImage(named: "placeholder"))
      logoImageView.translatesAutoresizingMaskIntoConstraints = false
      logoImageView.frame = CGRect(x: 0, y: 0, width: view.frame.width/1.8, height: 30)
      topView.addSubview(logoImageView)
  
      logoImageView.leftAnchor.constraint(greaterThanOrEqualTo: view.leftAnchor, constant: 20).isActive = true
      logoImageView.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor, constant: 30).isActive = true
  
      topView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
      topView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
      topView.heightAnchor.constraint(equalToConstant: view.frame.height/3).isActive = true
      topView.centerYAnchor.constraint(equalTo: view.topAnchor).isActive = true
      topView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
  
      //Generate and add Scroll View to Main Window
  
      let scrollView = UIScrollView()
      scrollView.translatesAutoresizingMaskIntoConstraints = false
      view.addSubview(scrollView)
  
      NSLayoutConstraint.activate([
          scrollView.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 20),
          scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
          scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
          scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
          scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
      ])
  
      //Add Content Stack to Scroll View
  
      contentView.axis = .vertical
      contentView.alignment = .fill
      contentView.spacing = 150
      contentView.distribution = .fill
      contentView.backgroundColor = .blue
      contentView.translatesAutoresizingMaskIntoConstraints = false
      scrollView.addSubview(contentView)
  
      NSLayoutConstraint.activate([
          contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
          contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 20),
          contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -20),
          contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
          contentView.widthAnchor.constraint(equalToConstant: scrollView.frame.width),
          contentView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
      ])
  
      // programmatically creating layout elements without constraints
      // Elements that change a value are always last in their respective array
  
      for (index, dropdownName) in dropdowns.enumerated() {
          constraints[dropdownName] = [[]]
          let label = UILabel()
          label.translatesAutoresizingMaskIntoConstraints = false
          label.text = dropdownName
  
          let leadAnch = label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          constraints[dropdownName]!.append([leadAnch])
  
          let textField = UITextField()
          textField.delegate = self
          textField.translatesAutoresizingMaskIntoConstraints = false
          textField.backgroundColor = .white
          textField.layer.cornerRadius = 5
  
          var trailAnch = textField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          var widthAnch = textField.widthAnchor.constraint(equalToConstant: view.frame.width / 6)
          constraints[dropdownName]!.append([trailAnch, widthAnch])
  
          let pickerView = UIPickerView()
          pickerView.backgroundColor = .white
          pickerView.translatesAutoresizingMaskIntoConstraints = false
          pickerView.delegate = self
          pickerView.isHidden = true
          pickerView.dataSource = self
  
          trailAnch = pickerView.trailingAnchor.constraint(equalTo: textField.trailingAnchor)
          widthAnch = pickerView.widthAnchor.constraint(equalTo: textField.widthAnchor)
          constraints[dropdownName]!.append([trailAnch, widthAnch])
  
          let dropdownWrapper = UIView()
          dropdownWrapper.translatesAutoresizingMaskIntoConstraints = false
  
          dropdownWrapper.addSubview(label)
          dropdownWrapper.addSubview(textField)
          dropdownWrapper.addSubview(pickerView)
  
          wrappers[dropdownName] = dropdownWrapper
          elements[dropdownName] = [label, textField, pickerView]
  
          let commandID = bleService.getCommand(commandName: dropdownName)
          bleService.send(aText: "c\(commandID)r:#")
      }
  
      for (index, sliderName) in sliders.enumerated() {
          constraints[sliderName] = [[]]
          let descLabel = UILabel()
          descLabel.translatesAutoresizingMaskIntoConstraints = false
          descLabel.text = sliderName
  
          var leadAnch = descLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          constraints[sliderName]!.append([leadAnch])
  
          let valueLabel = UILabel()
          valueLabel.translatesAutoresizingMaskIntoConstraints = false
          valueLabel.text = "0"
          valueLabel.backgroundColor = .white
  
          let widthAnch = valueLabel.widthAnchor.constraint(equalToConstant: view.frame.width/6)
          var trailAnch = valueLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          constraints[sliderName]!.append([trailAnch, widthAnch])
  
          let slider = UISlider()
          slider.translatesAutoresizingMaskIntoConstraints = false
          slider.isContinuous = false
          slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
  
          leadAnch = slider.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          trailAnch = slider.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          let topAnch = slider.topAnchor.constraint(equalTo: descLabel.bottomAnchor, constant: 5)
          constraints[sliderName]!.append([trailAnch, leadAnch, topAnch])
  
          let sliderWrapper = UIView()
          sliderWrapper.translatesAutoresizingMaskIntoConstraints = false
  
          sliderWrapper.addSubview(descLabel)
          sliderWrapper.addSubview(valueLabel)
          sliderWrapper.addSubview(slider)
  
          wrappers[sliderName] = sliderWrapper
          elements[sliderName] = [descLabel, valueLabel, slider]
  
          let commandID = bleService.getCommand(commandName: sliderName)
          bleService.send(aText: "c\(commandID)r:#")
      }
  
      for (index, checkboxName) in checkboxes.enumerated() {
          constraints[checkboxName] = [[]]
          let cbLabel = UILabel()
          cbLabel.translatesAutoresizingMaskIntoConstraints = false
          cbLabel.text = checkboxName
  
          let leadAnch = cbLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          constraints[checkboxName]!.append([leadAnch])
  
          let checkbox = UISwitch()
          checkbox.translatesAutoresizingMaskIntoConstraints = false
          checkbox.addTarget(self, action: #selector(checkboxClicked), for: .valueChanged)
  
          let trailAnch = checkbox.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          constraints[checkboxName]!.append([trailAnch])
  
          let checkboxWrapper = UIView()
          checkboxWrapper.translatesAutoresizingMaskIntoConstraints = false
  
          checkboxWrapper.addSubview(cbLabel)
          checkboxWrapper.addSubview(checkbox)
  
          wrappers[checkboxName] = checkboxWrapper
          elements[checkboxName] = [cbLabel, checkbox]
  
          let commandID = bleService.getCommand(commandName: checkboxName)
          bleService.send(aText: "c\(commandID)r:#")
      }
  
      for (index, textInputName) in textInputs.enumerated() {
          constraints[textInputName] = [[]]
          let textLabel = UILabel()
          textLabel.translatesAutoresizingMaskIntoConstraints = false
          textLabel.text = textInputName
  
          var leadAnch = textLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          constraints[textInputName]!.append([leadAnch])
  
          let inputField = UITextField()
          inputField.layer.cornerRadius = 5
          inputField.translatesAutoresizingMaskIntoConstraints = false
          inputField.placeholder = textInputs[index]
          inputField.backgroundColor = .white
          inputField.addTarget(self, action: #selector(textfieldChanged), for: .valueChanged)
  
          let topAnch = inputField.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: 5)
          let widthAnch = inputField.widthAnchor.constraint(equalToConstant: view.safeAreaLayoutGuide.layoutFrame.width/1.1)
          leadAnch = inputField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          constraints[textInputName]!.append([topAnch, widthAnch, leadAnch])
  
          let inputWrapper = UIView()
          inputWrapper.translatesAutoresizingMaskIntoConstraints = false
  
          inputWrapper.addSubview(textLabel)
          inputWrapper.addSubview(inputField)
  
          wrappers[textInputName] = inputWrapper
          elements[textInputName] = [textLabel, inputField]
  
          let commandID = bleService.getCommand(commandName: textInputName)
          bleService.send(aText: "c\(commandID)r:#")
      }
  
      for(index, phase) in timePickers.enumerated() {
          constraints[phase] = [[]]
          let descLabel = UILabel()
          descLabel.translatesAutoresizingMaskIntoConstraints = false
          descLabel.text = "Zeitschaltung \(index+1)"
  
          var leadAnch = descLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          constraints[phase]!.append([leadAnch])
  
          let enabledSwitch = UISwitch()
          enabledSwitch.translatesAutoresizingMaskIntoConstraints = false
          enabledSwitch.addTarget(self, action: #selector(changeTimerState), for: .valueChanged)
  
          var topAnch = enabledSwitch.topAnchor.constraint(equalTo: descLabel.topAnchor)
          var trailAnch = enabledSwitch.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          constraints[phase]!.append([trailAnch, topAnch])
  
          let showPickerButton = UIButton()
          showPickerButton.translatesAutoresizingMaskIntoConstraints = false
          showPickerButton.setTitle("Zeit auswählen", for: .normal)
          showPickerButton.backgroundColor = .darkGray
          showPickerButton.layer.cornerRadius = 5
          showPickerButton.addTarget(self, action: #selector(showTimePicker), for: .touchUpInside)
  
          topAnch = showPickerButton.topAnchor.constraint(equalTo: enabledSwitch.bottomAnchor, constant: 4)
          trailAnch = showPickerButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          constraints[phase]!.append([topAnch, trailAnch])
  
          let timePicker = UIDatePicker()
          timePicker.backgroundColor = .white
          timePicker.isHidden = true
          timePicker.translatesAutoresizingMaskIntoConstraints = false
          timePicker.datePickerMode = .time
          timePicker.addTarget(self, action: #selector(changeTimer), for: .valueChanged)
  
          topAnch = timePicker.bottomAnchor.constraint(equalTo: enabledSwitch.bottomAnchor)
          trailAnch = timePicker.trailingAnchor.constraint(equalTo: enabledSwitch.trailingAnchor)
          constraints[phase]!.append([topAnch, trailAnch])
  
          //Brightness Slider Value Label
  
          let sliderValLabel = UILabel()
          sliderValLabel.translatesAutoresizingMaskIntoConstraints = false
          sliderValLabel.text = "0"
          sliderValLabel.backgroundColor = .white
  
          trailAnch = sliderValLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          topAnch = sliderValLabel.topAnchor.constraint(equalTo: showPickerButton.bottomAnchor, constant: 10)
          var widthAnch = sliderValLabel.widthAnchor.constraint(equalToConstant: view.frame.width / 6)
          constraints[phase]!.append([trailAnch, topAnch, widthAnch])
  
          //Brightness Slider
  
          let valueSlider = UISlider()
          valueSlider.isContinuous = false
          valueSlider.translatesAutoresizingMaskIntoConstraints = false
  
          topAnch = valueSlider.topAnchor.constraint(equalTo: sliderValLabel.bottomAnchor, constant: 10)
          leadAnch = valueSlider.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
          trailAnch = valueSlider.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
          constraints[phase]!.append([topAnch, leadAnch, trailAnch])
  
          let timePickerWrapper = UIView()
          //timePickerWrapper.translatesAutoresizingMaskIntoConstraints = false
  
          timePickerWrapper.addSubview(descLabel)
          timePickerWrapper.addSubview(enabledSwitch)
          timePickerWrapper.addSubview(showPickerButton)
          timePickerWrapper.addSubview(timePicker)
          timePickerWrapper.addSubview(valueSlider)
          timePickerWrapper.addSubview(sliderValLabel)
  
          wrappers[phase] = timePickerWrapper
          elements[phase] = [descLabel, showPickerButton, enabledSwitch, timePicker, sliderValLabel, valueSlider]
  
          let commandID = bleService.getCommand(commandName: phase)
          bleService.send(aText: "c\(commandID)r:#")
      }
  
      for buttonName in buttons {
          constraints[buttonName] = [[]]
          let button = UIButton()
          button.translatesAutoresizingMaskIntoConstraints = false
  
          let widthAnch = button.widthAnchor.constraint(equalToConstant: contentView.frame.width/1.1)
          let xAnch = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
          constraints[buttonName]!.append([widthAnch, xAnch])
  
          let buttonWrapper = UIView()
          buttonWrapper.translatesAutoresizingMaskIntoConstraints = false
  
          wrappers[buttonName] = buttonWrapper
          elements[buttonName] = [button]
      }
  }        
  
  func changeContent(criteria: [String]) {
          for item in criteria {
              if(!contentView.contains(wrappers[item]!)) {
                  contentView.addArrangedSubview(wrappers[item]!)
                  for singleView in constraints[item]! {
                      for singleViewConstraint in singleView {
                          singleViewConstraint.isActive = true
                      }
                  }
              }
          }
      }
  
  func removeContent() {
      var criteria = [String]()
      switch(previousSetupMode) {
      case "d":
          criteria = d_kind_criteria
          break
      case "l":
          criteria = l_kind_criteria
          break
      case "m":
          criteria = m_kind_criteria
          break
      case "t":
          criteria = t_kind_criteria
          break
      default:
          break
      }
      for item in criteria {
          wrappers[item]!.removeFromSuperview()
      }
  }
  
  func changeView() {
      if(previousSetupMode != activeSetupMode) {
          removeContent()
      }
      switch(activeSetupMode) {
      case "d":
          changeContent(criteria: d_kind_criteria)
          break
      case "l":
          changeContent(criteria: l_kind_criteria)
          break
      case "t":
          changeContent(criteria: t_kind_criteria)
          break
      case "m":
          changeContent(criteria: m_kind_criteria)
          break
      default:
          break
      }
  }
  </code></pre>