Übergeben von Berührungsereignissen an entsprechende Geschwister UIViews


12

Ich versuche, Berührungsereignisse mit touchesBegan in einem Overlay zu einem übergeordneten UIView zu behandeln, aber erlaube auch, dass der Berührungseingang zu Geschwister UIView s darunter durchgeht. Ich erwartete, dass es eine direkte Methode geben würde, ein Berührungsereignis zu verarbeiten und dann zu sagen: "Sende es jetzt an den nächsten Responder, als ob dieser nicht existierte", aber alles, was ich finden kann, ist die Methode, die zu geben scheint Zurück zum übergeordneten Element in meiner Overlay-Ansicht. Dieses Elternteil gibt es dann nicht wirklich an das nächste Geschwister dieser Overlay-Ansicht weiter, so dass ich unsicher bin, wie ich eine einfache Aufgabe ausführen kann, die normalerweise mit einem Touch-Callback ausgeführt wird, der einen Wahr- oder Falsch-Rückgabewert erhält ob die Widget-Hierarchie weiter verarbeitet werden soll.

Fehle ich etwas offensichtlich?

3

Späte Antwort, aber ich denke, dass Sie besser hitTest:withEvent: anstelle von touchesBegan überschreiben würden. Es scheint mir, dass touchesBegan eine ziemlich "High-Level" -Methode ist, die da ist, um nur eine einfache Sache zu tun, so dass Sie auf dieser Ebene nicht ändern können, wenn das Ereignis weiter propagiert wird. Der richtige Ort dafür ist hitTest:withEvent:.

Weitere Informationen zu diesem Punkt finden Sie unter this S.O. answer.


1

Ich verstehe das gewünschte Verhalten, das Sie suchen Joey - Ich habe nicht etwas in der API gefunden, die diese automatische Messaging-up-the-Chain-Verhalten mit Geschwisteransichten unterstützt.

Was ich ursprünglich unten schrieb, war in Bezug auf nur ein Elternteil UIView über eine Berührung zu informieren. Dies gilt immer noch, aber ich glaube, Sie müssen noch einen Schritt weiter gehen und das UIView-Elternelement die von Sergio beschriebene Hit-Testmethode für jede seiner Unteransichten verwenden, die mit der Überlagerung gleichrangig sind, und die Eltern-UIView manuell ein "do etwas "Methode auf jedem seiner Unteransichten, die den Hit-Test bestehen. Jede dieser gleichgeordneten Ansichten kann einen BOOL-Wert zurückgeben, der angibt, ob die Benachrichtigung anderer Geschwister abgebrochen oder die Kette fortgesetzt werden soll.

Wenn Sie dieses Muster häufig verwenden, sollten Sie eine Kategoriemethode in UIView hinzufügen, die die Treffertests einbezieht und Ansichten fragt, um einen Selektor auszuführen.

My Original Antwort

Mit ein wenig Handarbeit, können Sie diesen Draht selbst zusammen. Ich musste dies tun, und es funktionierte für mich, weil ich einen oft wiederholten Anwendungsfall hatte (eine Überlagerungsansicht auf einer Schaltfläche), wo es sinnvoll war, einige benutzerdefinierte Klassen zu erstellen. Wenn Ihre Situation ähnlich ist, wird eine dieser Techniken ausreichen.

Option 1: Wenn das Overlay braucht nichts zu tun, aber hübsch aussehen, haben sie aus der Berührung entscheiden vollständig mit userInteractionEnabled = NO Handhabung. Dies bewirkt, dass das Berührungsereignis an seine Eltern-UIView (die eine Überlagerung ist) geht.

Option 2: Haben die Overlay absorbieren die Berührungsereignis (wie es standardmäßig würde), und dann ein Verfahren auf der übergeordneten UIView aufrufen anzeigt, dass eine Berührung oder bestimmte Geste erkannt wurde, und hier ist, was es ist. Auf diese Weise kann die UIView hinter dem Overlay immer noch auf die Berührungserkennung einwirken, auch wenn jemand anderes die Interception durchgeführt hat.

Mit Option 2 ist es eher für einfache UIControlEvent Typen geeignet, wie UIControlEventTouchDown und UIControlEventTouchUpInside.In meinem Fall (eine benutzerdefinierte UIButton Unterklasse mit einer benutzerdefinierten Overlay-Ansicht darüber), werde ich Touch-Down-und Touch-up-Ereignisse auf der Schaltfläche auf zwei verschiedene Methoden. Diese feuern, wenn ein Aufsetz- oder Nachbesserungs-Innenereignis auf dem Knopf selbst auftritt. Aber es sind auch Hooks, die ich aus der Overlay-Ansicht aufrufen kann, wenn ich simulieren muss, dass ein Tastendruck stattgefunden hat.

Je nach Bedarf könnten Sie ein bekanntes Protokoll zwischen dem Overlay haben und es ist UIView Eltern oder einfach nur das Overlay die UIView testen informell, mit einem respondsToSelector: Check vor performSelector: auf es mit der benutzerdefinierten Methode aufgerufen Sie aufgerufen wollen das würde automatisch ausgelöst, wenn die UIView nicht von einem Overlay überdeckt wurde.