Событие касания не регистрируется за пределами дочернего UIView, который частично выходит за пределы родительского UIView - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть родительское представление, которое содержит два элемента.По сути, они содержат раскрывающийся список.Ссылка на изображение ниже: при нажатии на синий элемент отображается (изначально скрытый) раскрывающийся список UITableView.Этот UITableView частично находится внутри того же родительского представления, которое также содержит синий элемент.

enter image description here

Когда я пытаюсь щелкнуть одну из UITableViewCells, только первая ячейка регистрирует событие касания.Если табличное представление расположено так, что первая ячейка частично находится внутри родительского элемента, щелкает только та половина изображения, которая находится внутри родительского регистра.

Кажется, это проблема иерархии.Я попытался:

  1. Настройка Z-индексов
  2. Расположение всего UITableView вне родителя в иерархии раскадровки, но визуально позиционирование его внутри него.

Я не уверен, как поступить.

РЕДАКТИРОВАТЬ:

См. Ответ Андреа, который работал для меня.В итоге я переопределил метод point, как было предложено, и не использовал hitTest.Однако я пошел с другой реализацией переопределения метода point:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    if super.point(inside: point, with: event) { return true }
    for subview in subviews {
        let subviewPoint = subview.convert(point, from: self)
        if subview.point(inside: subviewPoint, with: event) { return true }
    }
    return false
}

1 Ответ

0 голосов
/ 29 ноября 2018

Как писал ДонМаг:

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

По крайней мере, не безпереопределяя некоторые методы, представления имеют свои собственные реализации для обнаружения касаний.Наиболее важные методы:

func hitTest(_ point: CGPoint, 
        with event: UIEvent?) -> UIView?

func point(inside point: CGPoint, 
      with event: UIEvent?) -> Bool

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

class GreedyTouchView: UIView {
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if !self.clipsToBounds && !self.isHidden && self.alpha > 0.0 {
            let subviews = self.subviews.reversed()
            for member in subviews {
                let subPoint = member.convert(point, from: self)
                if let result: UIView = member.hitTest(subPoint, with:event) {
                    return result
                }
            }
        }
        return super.hitTest(point, with: event)
    }
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return super.point(inside: point, with: event)
    }
}


Но я хотел бы отметить, что выпадающие меню больше связаны с веб-интерфейсом, а не с iOSСвязанный с пользовательским интерфейсом, вы должны использовать вместо этого выбора.

...