Angenommen, wir haben einen View Controller mit einer Unteransicht. Die Unteransicht nimmt die Mitte des Bildschirms mit 100 px Rändern auf allen Seiten ein. Wir fügen dann ein paar Kleinigkeiten hinzu, auf die wir in dieser Unteransicht klicken können. Wir verwenden die Unteransicht nur, um den neuen Frame zu nutzen (x = 0, y = 0 in der Unteransicht beträgt in der übergeordneten Ansicht tatsächlich 100.100).
Stellen Sie sich dann vor, wir hätten etwas hinter der Unteransicht, wie ein Menü. Ich möchte, dass der Benutzer in der Lage ist, eines der "kleinen Dinge" in der Unteransicht auszuwählen, aber wenn dort nichts ist, möchte ich, dass Berührungen (da der Hintergrund sowieso klar ist) zu den Schaltflächen dahinter gelangen.
Wie kann ich das machen? Es sieht so aus, als würde touchBegan durchlaufen, aber die Tasten funktionieren nicht.
quelle
UIButton
, die sich unter einer halbtransparenten befindet,UIView
während der nicht transparente Teil derUIView
weiterhin auf Berührungsereignisse reagiert.Antworten:
Erstellen Sie eine benutzerdefinierte Ansicht für Ihren Container und überschreiben Sie die Nachricht pointInside:, um false zurückzugeben, wenn sich der Punkt nicht in einer berechtigten untergeordneten Ansicht befindet.
Schnell:
Ziel c:
Wenn Sie diese Ansicht als Container verwenden, können alle untergeordneten Elemente Berührungen erhalten, die Ansicht selbst ist jedoch für Ereignisse transparent.
quelle
Ich benutze auch
Keine Notwendigkeit für Unterklassen. Funktioniert gut.
quelle
Von Apple:
Best Practice für Äpfel :
Stattdessen können Sie Folgendes überschreiben:
in Ihrer UIView-Unterklasse und geben Sie NEIN zurück, wenn Sie möchten, dass diese Berührung über die Responderkette gesendet wird (IE für Ansichten hinter Ihrer Ansicht, in denen sich nichts befindet).
quelle
NO
;Eine weitaus einfachere Möglichkeit besteht darin, die im Interface Builder aktivierte Benutzerinteraktion zu deaktivieren. "Wenn Sie ein Storyboard verwenden"
quelle
Aufbauend auf dem, was John gepostet hat, ist hier ein Beispiel, mit dem Berührungsereignisse alle Unteransichten einer Ansicht mit Ausnahme der Schaltflächen durchlaufen können:
quelle
UIView
UnterklassePassThroughView
, die nur überschrieben wird,-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { return YES; }
wenn Sie Berührungsereignisse an Unteransichten weiterleiten möchten.In letzter Zeit habe ich eine Klasse geschrieben, die mir dabei helfen wird. Verwenden Sie es als benutzerdefinierte Klasse für ein
UIButton
oderUIView
mehrere Berührungsereignisse verwenden, die auf einem transparenten Pixel ausgeführt wurden.Diese Lösung ist etwas besser als die akzeptierte Antwort, da Sie immer noch auf eine Antwort klicken können
UIButton
, die sich unter einer halbtransparenten befindet,UIView
während der nicht transparente Teil der LösungUIView
weiterhin auf Berührungsereignisse reagiert.Wie Sie im GIF sehen können, ist die Giraffenschaltfläche ein einfaches Rechteck, aber Berührungsereignisse in transparenten Bereichen werden an das
UIButton
darunter liegende Gelb weitergeleitet .Link zur Klasse
quelle
Die am besten gewählte Lösung funktionierte für mich nicht vollständig. Ich glaube, das lag daran, dass ich einen TabBarController in der Hierarchie hatte (wie einer der Kommentare hervorhebt), der tatsächlich Berührungen an einige Teile der Benutzeroberfläche weitergab, aber mit meiner durcheinander war Die Fähigkeit von tableView, Berührungsereignisse abzufangen, hat letztendlich hitTest in der Ansicht überschrieben. Ich möchte Berührungen ignorieren und die Unteransichten dieser Ansicht damit umgehen lassen
quelle
Swift 3
quelle
Laut dem 'Programmierhandbuch für iPhone-Anwendungen':
http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/EventHandling/EventHandling.html
Aktualisiert : Beispiel entfernt - Frage erneut lesen ...
Haben Sie eine Gestenverarbeitung für die Ansichten, die möglicherweise die Taps verarbeiten, bevor die Schaltfläche sie erhält? Funktioniert die Schaltfläche, wenn Sie keine transparente Ansicht darüber haben?
Irgendwelche Codebeispiele für nicht funktionierenden Code?
quelle
Soweit ich weiß, sollten Sie dies tun können, indem Sie die Methode hitTest: überschreiben . Ich habe es versucht, konnte es aber nicht richtig zum Laufen bringen.
Am Ende habe ich eine Reihe transparenter Ansichten um das berührbare Objekt erstellt, damit sie es nicht abdecken. Ein bisschen wie ein Hack für mein Problem, das hat gut funktioniert.
quelle
Ausgehend von den anderen Antworten und dem Lesen der Apple-Dokumentation habe ich diese einfache Bibliothek zur Lösung Ihres Problems erstellt:
https://github.com/natrosoft/NATouchThroughView
Es erleichtert das Zeichnen von Ansichten in Interface Builder, an die Berührungen weitergeleitet werden sollen eine zugrunde liegende Ansicht.
Ich denke, Methoden-Swizzling ist übertrieben und im Produktionscode sehr gefährlich, da Sie direkt mit der Basisimplementierung von Apple herumspielen und eine anwendungsweite Änderung vornehmen, die unbeabsichtigte Konsequenzen haben kann.
Es gibt ein Demo-Projekt und hoffentlich macht die README einen guten Job und erklärt, was zu tun ist. Um das OP zu adressieren, würden Sie die übersichtliche UIView, die die Schaltflächen enthält, ändern, um NATouchThroughView in Interface Builder zu klassifizieren. Suchen Sie dann die übersichtliche UIView, die das Menü überlagert, auf das Sie tippen möchten. Ändern Sie diese UIView im Interface Builder in die Klasse NARootTouchThroughView. Es kann sogar die Stamm-UIView Ihres View-Controllers sein, wenn Sie beabsichtigen, diese Berührungen an den zugrunde liegenden View-Controller weiterzuleiten. Schauen Sie sich das Demo-Projekt an, um zu sehen, wie es funktioniert. Es ist wirklich ganz einfach, sicher und nicht invasiv
quelle
Ich habe dazu eine Kategorie erstellt.
eine kleine Methode swizzling und die Aussicht ist golden.
Der Header
Die Implementierungsdatei
Sie müssen meine Swizz.h und Swizz.m hinzufügen
befindet sich hier
Danach importieren Sie einfach die Datei UIView + PassthroughParent.h in Ihre Datei {Project} -Prefix.pch, und jede Ansicht verfügt über diese Funktion.
Jede Ansicht nimmt Punkte ein, aber keine der leeren Stellen.
Ich empfehle auch einen klaren Hintergrund.
BEARBEITEN
Ich habe meine eigene Eigentumstasche erstellt, die vorher nicht enthalten war.
Header-Datei
Implementierungsdatei
quelle
pointInside: withEvent:
?Wenn Sie sich nicht die Mühe machen können, eine Kategorie oder Unterklasse UIView zu verwenden, können Sie die Schaltfläche auch einfach nach vorne bringen, sodass sie sich vor der transparenten Ansicht befindet. Dies ist abhängig von Ihrer Anwendung nicht immer möglich, hat aber bei mir funktioniert. Sie können den Knopf jederzeit wieder zurückbringen oder ausblenden.
quelle
Versuche dies
quelle
Versuchen Sie, eine
backgroundColor
IhrertransparentView
alsUIColor(white:0.000, alpha:0.020)
. Dann können Sie Berührungsereignisse intouchesBegan
/touchesMoved
Methoden abrufen. Platzieren Sie den Code unten an einer Stelle, an der Ihre Ansicht angezeigt wird:quelle
Ich benutze das, anstatt den Methodenpunkt zu überschreiben (innerhalb von: CGPoint, mit: UIEvent)
quelle