UIView не виден, когда внутри подпредставления - PullRequest
0 голосов
/ 07 апреля 2020

Внутри моего проекта у меня есть Custom-DropDownView. Проблема в том, что фактическое значение DropView не появляется при нажатии DropDownButton, если DropDownButton находится внутри Subview.

Моя структура: ViewController -> UIView -> UIStackView -> arrangedSubview -> DropdownButton

Если добавить DropDownButton внутри ViewController работает просто отлично. Однако, если я добавлю его в StackView (где он мне действительно нужен), он не покажет dropView, который должен появиться, когда пользователь нажимает DropDownButton.

DropDownButton :

class DropDownBtn: UIButton, DropDownProtocol {

let label: UILabel = {
   let v = UILabel()
    v.font = UIFont(name: "AvenirNext-Regular", size: 15)
    v.textColor = .white
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()

let listImage: UIImageView = {
    let v = UIImageView()
    v.backgroundColor = .clear
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()

func dropDownPressed(string: String, image: UIImage) {
    self.setTitle("", for: .normal)
    self.label.text = string
    self.listImage.image = image
    self.dismissDropDown()
}

var dropView = DropDownView()

var height = NSLayoutConstraint()


override init(frame: CGRect) {
    super.init(frame: frame)

    self.backgroundColor = UIColor.clear
    self.layer.borderColor = UIColor.white.cgColor
    self.layer.borderWidth = 1.0
    self.layer.cornerRadius = 3


    // add image
    self.addSubview(listImage)
    self.listImage.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
    self.listImage.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    self.listImage.widthAnchor.constraint(equalToConstant: 22).isActive = true
    self.listImage.heightAnchor.constraint(equalToConstant: 22).isActive = true

    // add label
    self.addSubview(label)
    self.label.leadingAnchor.constraint(equalTo: self.listImage.leadingAnchor, constant: 32).isActive = true
    self.label.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

    dropView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
    dropView.delegate = self
    dropView.layer.borderColor = UIColor.white.cgColor
    dropView.layer.borderWidth = 1.0
    dropView.translatesAutoresizingMaskIntoConstraints = false
}

override func didMoveToSuperview() {
    self.superview?.addSubview(dropView)
    self.superview?.bringSubviewToFront(dropView)
    dropView.bottomAnchor.constraint(equalTo: self.topAnchor).isActive = true
    dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
    dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
    height = dropView.heightAnchor.constraint(equalToConstant: 0)
}

override func removeFromSuperview() {        
    dropView.bottomAnchor.constraint(equalTo: self.topAnchor).isActive = false
    dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = false
    dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = false
}

var isOpen = false

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    if isOpen == false {

        isOpen = true

        NSLayoutConstraint.deactivate([self.height])

        if self.dropView.tableView.contentSize.height > 150 {
            self.height.constant = 150
        } else {
            self.height.constant = self.dropView.tableView.contentSize.height
        }


        NSLayoutConstraint.activate([self.height])

        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
            self.dropView.layoutIfNeeded()
            self.dropView.center.y -= self.dropView.frame.height / 2
        }, completion: nil)

    } else {
        isOpen = false

        NSLayoutConstraint.deactivate([self.height])
        self.height.constant = 0
        NSLayoutConstraint.activate([self.height])
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
            self.dropView.center.y += self.dropView.frame.height / 2
            self.dropView.layoutIfNeeded()
        }, completion: nil)

    }
}

func dismissDropDown() {
    isOpen = false
    NSLayoutConstraint.deactivate([self.height])

    self.height.constant = 0
    NSLayoutConstraint.activate([self.height])
    UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseIn, animations: {
        self.dropView.center.y += self.dropView.frame.height / 2
        self.dropView.layoutIfNeeded()
    }, completion: nil)

}

Использование в данный момент:

Внутри UIView:

let dropDownButton: DropDownBtn = {
        let v = DropDownBtn()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

, и я добавляю его вот так (+ используя autolayout, кнопка отображается отлично и не позади других view):

theStackView.addArrangedSubview(self.itemView)
itemView.addSubview(dropDownButton)

Я пытался позвонить self.view.bringSubViewToFront(self.view.theUIView.dropDownButton.dropView), но это ничего не помогало. фактический DropDownButton кажется в порядке. Я проверил это в View-Hierarchy, и я также проверил, что touchesBegan на самом деле называется и так оно и есть.

Так что я думаю, проблема в том, как я ограничиваю dropView, но я полностью застрял здесь. Если кто-то может помочь мне здесь, я очень благодарен!

Если что-то неясно или вам нужно больше кода, просто дайте мне знать!

Обновление:

Причина, по которой tableView не была видна потому что я забыл позвонить reloadData. Однако это не решает основную проблему!

tableView не активируется при добавлении в arrangedSubview. Только если я добавлю его в UIView напрямую, он станет кликабельным. В обоих случаях иерархия представления выглядит одинаково. Она всегда впереди.

Если вы хотите посмотреть сами, дайте мне знать, и я дам вам ссылку на проект.

...