Ответ
Нет, напрямую — нельзя. Когда isUserInteractionEnabled = false, система UIKit полностью игнорирует все жесты и касания на этом представлении. Однако существуют обходные пути для перехвата событий:
1. Прозрачное наложение (Overlay View)
Добавьте поверх целевой вью прозрачное представление с включенным взаимодействием.
let overlay = UIView(frame: targetView.bounds)
overlay.isUserInteractionEnabled = true
targetView.addSubview(overlay)
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
overlay.addGestureRecognizer(tapRecognizer)
2. Переопределение hitTest(_:with:)
Можно перехватить и перенаправить события, переопределив метод hitTest в кастомной вью.
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
// Возвращаем nil для себя, чтобы события прошли "сквозь" эту вью
return hitView == self ? nil : hitView
}
3. Программный вызов действий (для UIControl)
Для элементов UIControl (кнопки, слайдеры) можно использовать метод sendActions(for:) для программной отправки событий.
button.sendActions(for: .touchUpInside)
Важно: Эти методы являются обходными и могут усложнить архитектуру. Основное правило — если вью должна реагировать на касания, isUserInteractionEnabled должно быть true.
Ответ 18+ 🔞
А, ну это же классика, блядь! Ситуация, когда ты пытаешься ткнуть в кнопку, а она как будто из другого измерения, нихуя не реагирует. isUserInteractionEnabled = false — это как повесить на дверь табличку «Не еби мозги, я в отпуске». Система тупо смотрит на это и говорит: «Ну всё, пошёл нахуй, чувак, не моё дело».
Но мы же не ищем лёгких путей, правда? Нам надо, чтобы эта штука, которая официально «не в сети», всё-таки как-то откликалась. Ну что ж, держи несколько способов, как обойти эту хуйню, как настоящий гандон-разработчик.
Первый способ — накинуть сверху плёнку. Самый простой и тупой, как валенок. Берёшь прозрачную вьюху (UIView), накрываешь ею свою нерабочую кнопку или вью, и ловишь тапы уже по этой плёнке.
let overlay = UIView(frame: targetView.bounds)
overlay.isUserInteractionEnabled = true
targetView.addSubview(overlay)
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
overlay.addGestureRecognizer(tapRecognizer)
Получается этакий подставной слушатель, который кричит: «Эй, система, я тут! Тычь в меня!», пока оригинальная вьюха притворяется мёртвой. Хитрая жопа, но работает.
Второй способ — магия hitTest. Это уже для тех, кто любит покопаться в кишках. Создаёшь свою кастомную вьюху и переопределяешь этот метод.
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
// Возвращаем nil для себя, чтобы события прошли "сквозь" эту вью
return hitView == self ? nil : hitView
}
Суть в чём? Ты говоришь системе: «Знаешь что, когда ты ищешь, куда попали, и находишь меня — просто сделай вид, что меня нет. Иди искать дальше, вон там, подо мной, что-то интересное лежит». Событие пролетает сквозь тебя, как пуля сквозь говно, и попадает в то, что ниже. Ёперный театр, но иногда это единственный выход.
Третий способ — для кнопок, которые просто стесняются. Если у тебя UIControl (кнопка, свитч, слайдер), а он выключен, можно просто сымитировать нажатие программно, без всяких жестов.
button.sendActions(for: .touchUpInside)
Крикнул на неё — и она, блядь, сработала, как будто её ткнули. Прям как в том анекдоте: «Я не нажимал, это оно само!».
Но запомни главное, чувак: все эти финты ушами — это костыли, ебать мои старые костыли! Если вьюха по задумке должна отзываться на тап — включай ей isUserInteractionEnabled = true и не выёбывайся. А эти трюки — для особых, ебучьих случаев, когда архитектура проекта уже напоминает свалку и переделывать всё — терпения ноль ебать. Используй с умом, а то так и до багов, от которых волосы дыбом встанут, недалеко.