Warum passiert das?
Dies liegt daran, dass Berührungsereignisse, die tatsächlich in dieser Unteransicht auftreten, nicht an diese Unteransicht gesendet werden, wenn Ihre Unteransicht außerhalb der Grenzen Ihrer Übersicht liegt. Es ist jedoch WILL seine Superview geliefert werden.
Unabhängig davon, ob Unteransichten visuell abgeschnitten sind oder nicht, berücksichtigen Berührungsereignisse immer das Begrenzungsrechteck der Übersichtsansicht der Zielansicht. Mit anderen Worten, Berührungsereignisse, die in einem Teil einer Ansicht auftreten, der außerhalb des Rechtecks der Begrenzungsansicht liegt, werden nicht an diese Ansicht übergeben. Verknüpfung
Was musst du machen?
Wenn Ihre Übersicht das oben erwähnte Berührungsereignis empfängt, müssen Sie UIKit ausdrücklich mitteilen, dass meine Unteransicht diejenige sein sollte, die dieses Berührungsereignis empfängt.
Was ist mit dem Code?
Implementieren Sie in Ihrer Übersicht 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)
}
Faszinierende Gotchya: Sie müssen zur "höchsten zu kleinen Übersicht" gehen
Sie müssen "nach oben" zur "höchsten" Ansicht gehen, in der sich die Problemansicht befindet.
Typisches Beispiel:
Angenommen, Sie haben einen Bildschirm S mit einer Containeransicht C. Die Ansicht des Container Viewcontrollers ist V. (Rückruf V befindet sich innerhalb von C und hat die gleiche Größe.) V hat eine Unteransicht (möglicherweise eine Schaltfläche) B. B ist das Problem Ansicht, die tatsächlich außerhalb von V liegt.
Beachten Sie jedoch, dass B auch außerhalb von C liegt.
In diesem Beispiel haben Sie die Lösung anzuwenden override hitTest
und zwar bis C, nicht zu V . Wenn Sie es auf V anwenden, tut es nichts.