Чому це відбувається?
Це пов’язано з тим, що коли ваш підзапис знаходиться поза межами вашого суперпогляду, події дотику, які насправді відбуваються в цьому підпрогляді, не будуть доставлені до цього підпрогляду. Однак він БУДЕ доставлений до свого супервізу.
Незалежно від того, підзаголовки відсікаються візуально, події дотику завжди поважають прямокутник меж суперперегляду цільового подання. Іншими словами, події дотику, що відбуваються в частині подання, що лежить за межами прямокутника меж нагляду, не доставляються до цього подання. Посилання
Що потрібно зробити?
Коли ваша суперперегляд отримує згадану вище подію дотику, вам потрібно буде прямо сказати UIKit, що саме моя підпрограма повинна приймати цю подію дотику.
А як щодо коду?
У своєму супервиході реалізуйте func hitTest(_ point: CGPoint, with event: UIEvent?)
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if isHidden || alpha == 0 || clipsToBounds { return super.hitTest(point, with: event) }
// convert the point into subview's coordinate system
let subviewPoint = self.convert(point, to: subview)
// if the converted point lies in subview's bound, tell UIKit that subview should be the one that receives this event
if !subview.isHidden && subview.bounds.contains(subviewPoint) { return subview }
return super.hitTest(point, with: event)
}
Захоплююче chотчія: ви повинні перейти до "найвищого занадто малого суперпогляду"
Ви повинні піднятися "вгору" до "найвищого" подання, яке знаходиться поза зоною проблеми.
Типовий приклад:
Скажімо, у вас є екран S, з видом на контейнер C. Вигляд контролера перегляду контейнера - V. (Згадайте, V буде сидіти всередині C і буде однакового розміру.) V має підпрогляд (можливо, кнопку) B. B - проблема погляд, який насправді знаходиться поза межами В.
Але зверніть увагу, що B також знаходиться поза межами C.
У цьому прикладі ви повинні застосувати рішення override hitTestнасправді С, не до V . Якщо застосувати його до V - це нічого не робить.