如何防止一个 UIView 被另一个 UIView 隐藏?

How do I prevent one UIView from being hidden by another UIView?

我正在使用 UIViews 创建一个自定义的、可重复使用的分段控制器,但我遇到了重叠视图的问题。目前看起来像这样:

您可以看到蓝色选择器在 按钮下方,但我希望它位于 底部并且有四个像素高.为此,我有:

let numberOfButtons = CGFloat(buttonTitles.count)
let selectorWidth = frame.width / numberOfButtons
let selectorYPosition = frame.height - 3 <--- This cause it to be hidden behind the button
selector = UIView(frame: CGRect(x: 0, y: selectorYPosition, width: selectorWidth, height: 4))
selector.layer.cornerRadius = 0
selector.backgroundColor = selectorColor
addSubview(selector)
bringSubviewToFront(selector) <--- I thought this would work but it does nothing

这导致选择器 UIView 隐藏在段 UIView 后面(我将 Y 位置设置为 - 3 这样您就可以看到它是如何被掩盖的。我实际上希望它是 - 4,但这使它完全消失了):

我认为使用 bringSubviewToFront() 会将其置于段 UIView 之前,但它似乎没有任何作用。我查看了 Apple View Programming Guide 和许多 SO 线程,但找不到答案。

谁能帮我看看我错过了什么?

完整代码:

class CustomSegmentedControl: UIControl {
  var buttons = [UIButton]()
  var selector: UIView!
  var selectedButtonIndex = 0

  var borderWidth: CGFloat = 0 {
    didSet {
      layer.borderWidth = borderWidth
    }
  }

  var borderColor: UIColor = UIColor.black {
    didSet {
      layer.borderColor = borderColor.cgColor
    }
  }

  var separatorBorderColor: UIColor = UIColor.lightGray {
    didSet {

    }
  }

  var commaSeparatedTitles: String = "" {
    didSet {
      updateView()
    }
  }

  var textColor: UIColor = .lightGray {
    didSet {
      updateView()
    }
  }

  var selectorColor: UIColor = .blue {
    didSet {
      updateView()
    }
  }

  var selectorTextColor: UIColor = .black {
    didSet {
      updateView()
    }
  }

  func updateView() {
    buttons.removeAll()
    subviews.forEach { [=11=].removeFromSuperview() }

    // create buttons
    let buttonTitles = commaSeparatedTitles.components(separatedBy: ",")
    for buttonTitle in buttonTitles {
      let button = UIButton(type: .system)
      button.setTitle(buttonTitle, for: .normal)
      button.setTitleColor(textColor, for: .normal)
      button.backgroundColor = UIColor.white
      button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
      buttons.append(button)
    }

    // make first button selected
    buttons[0].setTitleColor(selectorTextColor, for: .normal)

    let numberOfButtons = CGFloat(buttonTitles.count)
    let selectorWidth = frame.width / numberOfButtons
    let selectorYPosition = frame.height - 3
    selector = UIView(frame: CGRect(x: 0, y: selectorYPosition, width: selectorWidth, height: 4))
    selector.layer.cornerRadius = 0
    selector.backgroundColor = selectorColor
    addSubview(selector)
    bringSubviewToFront(selector)

    let stackView = UIStackView(arrangedSubviews: buttons)
    stackView.axis = .horizontal
    stackView.alignment = .fill
    stackView.distribution = .fillEqually
    addSubview(stackView)

    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    stackView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    stackView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
  }

  @objc func buttonTapped(button: UIButton) {
    for (buttonIndex, btn) in buttons.enumerated() {
      btn.setTitleColor(textColor, for: .normal)

      if btn == button {
        let numberOfButtons = CGFloat(buttons.count)
        let selectorStartPosition = frame.width / numberOfButtons * CGFloat(buttonIndex)
        UIView.animate(withDuration: 0.3, animations: { self.selector.frame.origin.x = selectorStartPosition })
        btn.setTitleColor(selectorTextColor, for: .normal)
      }
    }

    sendActions(for: .valueChanged)

  }

}

你正在用 stackView 掩盖你的 selector

您需要做的:

bringSubviewToFront(selector)

添加完所有视图后。将该行移动到 updateView().

的底部