Ответ
По умолчанию UIGestureRecognizer перехватывает и обрабатывает касания, не передавая их в Responder Chain. Для интеграции необходимо настроить распознаватель жестов и/или вручную передавать события.
Основной подход: Установите свойство cancelsTouchesInView в false. Это позволяет касаниям достигать представления и быть переданы дальше по цепочке.
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tapGesture.cancelsTouchesInView = false // Ключевая настройка
view.addGestureRecognizer(tapGesture)
Расширенный подход: Ручная передача событий.
Если нужен полный контроль, можно переопределить методы UIResponder в подклассе UIView и передавать события вручную.
class CustomView: UIView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 1. Обрабатываем касание локально (опционально)
print("CustomView: Touch began")
// 2. Передаем событие следующему ответчику в цепочке
// Это может быть родительское view, UIViewControler и т.д.
next?.touchesBegan(touches, with: event)
}
// Аналогично для touchesMoved, touchesEnded, touchesCancelled
}
Типичный сценарий использования:
- Жест + цепочка ответчиков: Добавить кнопку поверх карты. Жест
UITapGestureRecognizerна карте должен обрабатывать тап, но не мешать кнопке получать событияUIControl. Решение:cancelsTouchesInView = false. - Кастомная обработка жестов: Создать собственный распознаватель, который обрабатывает сложные паттерны, но для стандартных касаний (например, выделения текста) передает управление в Responder Chain.
Итог: Используйте cancelsTouchesInView = false для базовой интеграции. Для сложных сценариев комбинируйте жесты с ручной пересылкой событий через next?.touchesBegan(...).