Реагировать на событие касания как для дочернего, так и для родительского

#ios #swift #uiview #ontouchlistener #event-bubbling

#iOS #swift #uiview #ontouchlistener #событие-пузырящийся

Вопрос:

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

Как мне это сделать?

Я попытался переопределить следующий метод в моем дочернем представлении, но возврат false здесь полностью игнорирует событие для дочернего устройства. И наоборот, если я обрабатываю событие касания в дочернем, оно игнорируется для родительского.

 override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return false
    }
  

Ответ №1:

Если у вас есть подклассы для обоих представлений, вы можете переопределить метод UIView touchesBegan. Если вы вызываете метод super touchesBegan , то это должно привести к результату, который вам нужен, когда событие перемещается вверх по цепочке ответчиков. (т. Е. Если пользователь нажимает на дочернее представление, событие касания как для дочернего, так и для родительского будет реагировать)

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event)
    print("TOUCHED")
}
  

Ответ №2:

Краткий пример…

Коснитесь «innerView», и вы увидите два отладочных отпечатка «касания начались». Коснитесь «outerView», и вы увидите только одно.

 class TouchView: UIView {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        print("touches began in (self)")
    }

}

class TouchTestViewController: UIViewController {

    let innerView: TouchView = {
        let v = TouchView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .red
        return v
    }()

    let outerView: TouchView = {
        let v = TouchView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(outerView)
        outerView.addSubview(innerView)

        NSLayoutConstraint.activate([

            outerView.widthAnchor.constraint(equalToConstant: 300),
            outerView.heightAnchor.constraint(equalToConstant: 300),
            outerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            outerView.centerYAnchor.constraint(equalTo: view.centerYAnchor),

            innerView.widthAnchor.constraint(equalToConstant: 150),
            innerView.heightAnchor.constraint(equalToConstant: 150),
            innerView.centerXAnchor.constraint(equalTo: outerView.centerXAnchor),
            innerView.centerYAnchor.constraint(equalTo: outerView.centerYAnchor),

            ])

    }

}