Невозможно выбрать второй элемент в ячейке табличного представления поверх пользовательского - PullRequest
0 голосов
/ 26 марта 2020

кто-нибудь, пожалуйста, помогите мне, у меня есть выпадающий список, но я не могу выбрать его во втором ряду. Я не могу понять, почему, я пытаюсь играть с takeSubviewsToFront или обратно. Я пытаюсь использовать layer.zPosition, он все еще не может выбрать второй ряд, но когда я выбираю первый ряд, он работает. это моя автоматическая настройка макета неправильно?

вот мой пользовательский интерфейс и настройка кода

dropdownshit

// This is my custom Button

class GDropdownSchedule: UIButton {
    let headerLbl   = GTitleLabel(name: "Schedule Type".localized(), fontSize: 13, color: #colorLiteral(red: 0.4588235294, green: 0.4941176471, blue: 0.5647058824, alpha: 1))
    let bodyLbl     = GSubtitleLabel(name: "Additional Note".localized(), fontSize: 16, color: #colorLiteral(red: 0.09803921569, green: 0.09803921569, blue: 0.09803921569, alpha: 1))
    let dropDownIV  = GIconImageView(img: #imageLiteral(resourceName: "down-chevron"))
    var isOpen              = false
    let dropView    = DropDownView()
    var delegate: AddScheduleVCDelegate?
    var height: NSLayoutConstraint!
    override init(frame: CGRect) {
        super.init(frame: frame)
        configure()
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    private func configure() {
        backgroundColor     = #colorLiteral(red: 0.9764705882, green: 0.9764705882, blue: 0.9764705882, alpha: 1)
        layer.cornerRadius  = 5
        layer.borderWidth   = 1
        layer.borderColor   = #colorLiteral(red: 0.9411764706, green: 0.9411764706, blue: 0.9450980392, alpha: 1)
        dropView.completion = { text in
            self.bodyLbl.text = text
            self.bodyLbl.font = UIFont(name: "NunitoSans-Regular", size: 12)
            self.delegate?.toggleHide(selected: text)
            self.dismissDropDown()
        }
    }
    override func didMoveToSuperview() {
        addSubview(headerLbl)
        headerLbl.anchor(top: topAnchor, trailing: nil, bottom: nil, leading: leadingAnchor, topPadding: 10, rightPadding: 0, bottomPadding: 0, leftPadding: 10, width: 70, height: 18)
        addSubview(bodyLbl)
        bodyLbl.anchor(top: headerLbl.bottomAnchor, trailing: nil, bottom: bottomAnchor, leading: leadingAnchor, topPadding: 2, rightPadding: 10, bottomPadding: 10, leftPadding: 10, width: 0, height: 0)
        addSubview(dropDownIV)
        dropDownIV.tintColor = #colorLiteral(red: 0.2549019608, green: 0.3019607843, blue: 0.3568627451, alpha: 1)
        dropDownIV.anchor(top: nil, trailing: trailingAnchor, bottom: bottomAnchor, leading: nil, topPadding: 0, rightPadding: 18, bottomPadding: 17, leftPadding: 0, width: 12, height: 10)
        addSubview(dropView)
        dropView.translatesAutoresizingMaskIntoConstraints = false
        dropView.layer.zPosition = 1
        height = dropView.heightAnchor.constraint(equalToConstant: 0)
        NSLayoutConstraint.activate([
            dropView.topAnchor.constraint(equalTo: headerLbl.bottomAnchor),
            dropView.leadingAnchor.constraint(equalTo: leadingAnchor),
            dropView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if isOpen == false {
            isOpen = true
            NSLayoutConstraint.deactivate([height])
            if self.dropView.tableView.contentSize.height > 150 {
                height.constant = 150
            } else {
                height.constant = dropView.tableView.contentSize.height
            }
            NSLayoutConstraint.activate([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
            })
        } else {
            isOpen = false
            NSLayoutConstraint.deactivate([height])
            height.constant = 0
            NSLayoutConstraint.activate([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()
            })
        }
    }
    func dismissDropDown() {
        isOpen = false
        NSLayoutConstraint.deactivate([height])
        height.constant = 0
        NSLayoutConstraint.activate([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()
        })
    }
}
class DropDownView: UIView, UITableViewDelegate, UITableViewDataSource {
    let tableView           = UITableView()
    var options             = [String]()
    var completion: ((String) -> Void)?
    var isHideSchedule      = false
    override init(frame: CGRect) {
        super.init(frame: frame)
        configure()
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    private func configure() {
        translatesAutoresizingMaskIntoConstraints = false
        addSubview(tableView)
        tableView.backgroundColor = #colorLiteral(red: 0.9764705882, green: 0.9764705882, blue: 0.9764705882, alpha: 1)
        tableView.separatorStyle = .none
        tableView.delegate      = self
        tableView.dataSource    = self
        tableView.anchor(top: topAnchor, trailing: trailingAnchor, bottom: bottomAnchor, leading: leadingAnchor, topPadding: 0, rightPadding: 0, bottomPadding: 0, leftPadding: 0, width: 0, height: 0)
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return options.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = options[indexPath.row]
        cell.textLabel?.font = UIFont(name: "NunitoSans-Regular", size: 12)
        cell.textLabel?.textColor = #colorLiteral(red: 0.09803921569, green: 0.09803921569, blue: 0.09803921569, alpha: 1)
        cell.backgroundColor = #colorLiteral(red: 0.9764705882, green: 0.9764705882, blue: 0.9764705882, alpha: 1)
        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        completion?(options[indexPath.row])
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

// This is in my viewController, the chooseScheduleDropDown is my customButton
[chooseScheduleDropDown, entryView, chooseDateView, chooseClass, startTimeView, endTimeView, descriptionView, saveBtn].forEach {
            v in
            v.translatesAutoresizingMaskIntoConstraints = false
            scrollView.addSubview(v)
        }
        scrollView.insertSubview(entryView, belowSubview: chooseScheduleDropDown)

1 Ответ

2 голосов
/ 26 марта 2020

Из-за механизма проверки попадания

Вы добавляете dropView на кнопке GDropdownSchedule

Макет

        addSubview(dropView)
        dropView.translatesAutoresizingMaskIntoConstraints = false
        dropView.layer.zPosition = 1
        height = dropView.heightAnchor.constraint(equalToConstant: 0)
        NSLayoutConstraint.activate([
            dropView.topAnchor.constraint(equalTo: headerLbl.bottomAnchor),
            dropView.leadingAnchor.constraint(equalTo: leadingAnchor),
            dropView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])

По виду и по существующему code,

Рамка dropView находится за пределами кнопки GDropdownSchedule Частично.

Таким образом, вы можете видеть это, и ваш щелчок не работает.


Для отмены механизма проверки удара все в порядке

 class GDropdownSchedule: UIButton {

 // ...

   override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        // if the button is hidden/disabled/transparent it can't be hit
        if self.isHidden || !self.isUserInteractionEnabled || self.alpha < 0.01 { return nil }

        let dropViewF = dropView.frame


        var index = 9
        if bounds.contains(point){
            index = 0
        }

        if dropViewF.contains(point){
            index = 1
        }

        switch index {
        case 0:
            for subV in subviews.reversed(){
                let realPoint = subV.convert(point, from: self)
                let hit = subV.hitTest(realPoint, with: event)
                if let v = hit{
                    return v
                }
            }
            return self
        case 1:
            if dropView.alpha > 0.01{
                let realPoint = dropView.convert(point, from: self)
                let hit = dropView.hitTest(realPoint, with: event)
                if let v = hit{
                    return v
                }
            }
        default:
            ()
        }
        return nil
    }

 }

От Apple's Do c

hitTest (_: with:)

Этот метод обходит иерархию представления, вызывая точку (inside: with :) метода каждого подпредставления, чтобы определить, какое подпредставление должно получить событие касания.

Если точка (inside: with :) возвращает true, иерархия подпредставления аналогичным образом пересекается, пока не будет найден самый передний вид, содержащий указанную точку. Если представление не содержит точку, его ветвь иерархии представлений игнорируется.

Вам редко нужно вызывать этот метод самостоятельно, но вы можете переопределить его, чтобы скрыть сенсорные события от подпредставлений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...