В UIKit, когда UIView не может обработать касание (touch event)?

Ответ

UIView пропускает или не получает события касания при следующих условиях:

  • Свойства видимости и взаимодействия:
    • isUserInteractionEnabled = false
    • isHidden = true
    • alpha <= 0.01
  • Геометрия:
    • Касание произошло за пределами границ вью (bounds).
    • Если clipsToBounds = true, части вью за своими границами не получают события.
  • Перехват события другой вью: Вью с более высоким порядком в иерархии (расположенная поверх) может перехватить событие.
  • Кастомная логика hit-testing: Неправильная реализация методов hitTest(_:with:) или point(inside:with:) может привести к потере события.
    // Пример: вью игнорирует все касания
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return false
    }

Для отладки используйте:

  1. Debug View Hierarchy в Xcode для визуализации слоёв.
  2. Проверку флагов isUserInteractionEnabled, alpha, isHidden.
  3. Пошаговый анализ цепочки ответа (hit-test chain).

Ответ 18+ 🔞

Ага, слушай, вот эта вся история с UIView, которая внезапно начинает игнорировать твои тычки пальцем — это классика, просто пиздец. Сидишь, такой, ебашь код, а оно не работает. И ты уже готов монитор об стенку ебнуть. Так вот, чтобы не сойти с ума, давай разберём, где эта сука может спрятаться от твоих прикосновений.

Первое и самое тупое, на чём все обламываются — это свойства, которые просто вырубают вьюху напрочь. Запомни их как «Отче наш», блядь:

  • isUserInteractionEnabled = false — это прям выключатель, ёпта. Поставил в false и всё, вьюха превращается в картинку. Никаких тебе тапов, никаких свайпов — нихуя. Проверь первым делом, не забыл ли ты её обратно в true переключить.
  • isHidden = true — ну тут вообще очевидно. Спрятали вью — какого хуя она должна на касания реагировать? Её же нет, блядь.
  • alpha <= 0.01 — вот это уже хитрая жопа. Если прозрачность 0.01 или меньше, система автоматом считает вью невидимой и отключает для неё hit-testing. Так что если ты сделал alpha = 0.0 для анимации исчезновения, не удивляйся, что твоя кнопка перестала кликаться.

Дальше идёт геометрия, мать её. Тут два основных сценария:

  1. Касание за пределами bounds. Это святое, блядь. Ткнул пальцем мимо вьюхи — получил в ответ нихуя. Система проверяет координаты.
  2. clipsToBounds = true. Включил эту штуку — всё, что торчит за границы bounds, не только не видно, но и не кликабельно. Хотел сделать круглую кнопку с тенью, которая вылезает за края? Если тенью ткнуть — события не будет, ёпта. Об этом часто забывают.

Теперь про иерархию, эту ёбаную слоёную структуру. Представь: у тебя есть маленькая кнопка, а сверху на неё наложили другую, прозрачную, но большую вьюху (UIView). И эта верхняя вьюха, сука, перехватит все события, даже если она полностью прозрачная! Потому что hit-testing идёт сверху вниз, от самого верхнего сабвью. Так что смотри, что у тебя лежит поверх твоей несчастной кнопки.

И наконец, кастомная логика — наш главный враг и источник самых ебейших багов. Если ты или какой-нибудь умный разработчик до тебя накостыляли в методах хит-тестинга, то пиши пропало.

Вот смотри, классический пример, как нахуячить себе проблем:

// Пример: вью игнорирует все касания
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    return false // Вот этот пидарас шерстяной всё и ломает!
}

Написал такое — и всё, вьюха умерла для событий. Или в hitTest что-то не то вернул. Переопределял эти методы? Иди и проверь, не накосячил ли.

Как отлаживать этот пиздец?

  1. Debug View Hierarchy в Xcode — твой лучший друг. Запускаешь, смотришь, как вьюхи на самом деле лежат. Может, твоя кнопка под другой вьюхой, а может, её вообще на экране нет, блядь. Визуализация — сила.
  2. Проверь флаги, долбаёб! Просто пройдись в дебаггере или принтами: isUserInteractionEnabled, alpha, isHidden. В 80% случаев проблема где-то тут.
  3. Анализ цепочки hit-test chain. Мысленно или на бумажке пройдись: система получает тап, идёт в корневую вью, вызывает у неё hitTest, тот вызывает point(inside:). Потом идёт в сабвьюхи. Где в этой цепочке твоя вьюха выпадает? Вот там и копай.

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