Что такое HitTest в UIKit?

«Что такое HitTest в UIKit?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

HitTest — это механизм в UIKit для определения представления (UIView), которое должно получить и обработать касание в заданной точке. Система вызывает метод hitTest(_:with:) у корневого view окна, который рекурсивно проходит по иерархии представлений.

Критерии для участия в HitTest:

  1. isUserInteractionEnabled = true
  2. isHidden = false
  3. alpha > 0.01
  4. Касание находится внутри границ view (проверяется методом point(inside:with:)).

Логика работы:

  • Поиск начинается с корневого view и идет вглубь иерархии.
  • Подходящее view-потомок имеет приоритет над родительским.
  • Порядок обхода подпредставлений (subviews) — с конца (с верхних по z-index).

Пример переопределения для кастомного поведения:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // 1. Проверяем базовые условия
    guard isUserInteractionEnabled, !isHidden, alpha > 0.01 else {
        return nil
    }
    // 2. Проверяем, попадает ли точка в текущее view
    if self.point(inside: point, with: event) {
        // 3. Рекурсивно проверяем подпредставления (с конца)
        for subview in subviews.reversed() {
            let convertedPoint = subview.convert(point, from: self)
            if let hitView = subview.hitTest(convertedPoint, with: event) {
                return hitView
            }
        }
        // 4. Если ни одно подпредставление не обработало касание, возвращаем себя
        return self
    }
    return nil
}

Практическое применение: Переопределение hitTest используется для увеличения области касания, обработки касаний за пределами видимых границ или для создания нестандартных интерактивных элементов.