Внутри моего проекта у меня есть 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
напрямую, он станет кликабельным. В обоих случаях иерархия представления выглядит одинаково. Она всегда впереди.
Если вы хотите посмотреть сами, дайте мне знать, и я дам вам ссылку на проект.