Ich versuche herauszufinden, wie das richtig gemacht wird . Ich habe versucht, die Situation darzustellen:
Ich UITableView
füge a als Unteransicht von a hinzu UIView
. Der UIView
reagiert auf ein Tippen und pinchGestureRecognizer
, aber wenn er dies tut, reagiert die Tabellenansicht nicht mehr auf diese beiden Gesten (sie reagiert immer noch auf Wischen).
Ich habe es mit dem folgenden Code zum Laufen gebracht, aber es ist offensichtlich keine gute Lösung und ich bin sicher, dass es einen besseren Weg gibt. Dies wird in die UIView
(Übersicht) gestellt:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if([super hitTest:point withEvent:event] == self) {
for (id gesture in self.gestureRecognizers) {
[gesture setEnabled:YES];
}
return self;
}
for (id gesture in self.gestureRecognizers) {
[gesture setEnabled:NO];
}
return [self.subviews lastObject];
}
quelle
hitTest:withEvent:
oderpointInside:withEvent:
.return !(touch.view == givenView);
ob Sie nur eine bestimmte Ansicht ausschließen möchten oder ob Sie verhindernreturn !(touch.view.tag == kTagNumReservedForExcludingViews);
möchten, dass Ihr Erkenner die Berührung einer ganzen Reihe verschiedener Unteransichten verarbeitet.- (BOOL)isDescendantOfView:(UIView *)view
. Dies funktioniert auch gut,- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
wenn UIGestureRecognizer untergeordnet wird.Das Blockieren von Berührungsereignissen für Unteransichten ist das Standardverhalten. Sie können dieses Verhalten ändern:
quelle
translationInView
Methode deklariert . Die Implementierung der oben genannten UIGestureRecognizerDelegate-Methode würde daher nur zu einem Absturz mit Fehler führen... unrecognized selector sent to blah
. Verwenden Sie zur Überprüfung Folgendes :CGRectContainsPoint(subview.bounds, [recognizer locationInView:subview])
.Ich habe eine Dropdown-Unteransicht mit einer eigenen Tabellenansicht angezeigt. Infolgedessen
touch.view
würden die manchmal Klassen wie zurückgebenUITableViewCell
. Ich musste die Oberklasse (n) durchlaufen, um sicherzustellen, dass es die Unterklasse war, die ich dachte:quelle
Eine Möglichkeit besteht darin, Ihren Gestenerkenner zu unterordnen (falls Sie dies noch nicht
-touchesBegan:withEvent:
getan haben) und ihn so zu überschreiben , dass er bestimmt, ob jede Berührung in einer ausgeschlossenen Unteransicht begonnen hat, und-ignoreTouch:forEvent:
diese Berührung anfordert , wenn dies der Fall ist .Natürlich müssen Sie auch eine Eigenschaft hinzufügen, um die ausgeschlossene Unteransicht oder besser ein Array ausgeschlossener Unteransichten zu verfolgen.
quelle
Aufbauend auf der Antwort von @Pin Shih Wang . Wir ignorieren alle Taps außer denen in der Ansicht, die den Tap-Gestenerkenner enthält. Alle Taps werden wie gewohnt an die Ansichtshierarchie weitergeleitet
tapGestureRecognizer.cancelsTouchesInView = false
. Hier ist der Code in Swift3 / 4:quelle
Es ist möglich, auf das Erben einer Klasse zu verzichten.
Sie können gestureRecognizers in der Rückrufauswahl von gesture überprüfen
Wenn view.gestureRecognizers Ihren gestureRecognizer nicht enthält, ignorieren Sie ihn einfach
beispielsweise
Überprüfen Sie hier view.gestureRecognizers
quelle
singleTapGesture.cancelsTouchesInView = NO;
hinzugefügt zuviewDidLoad
obenIch habe eine UIGestureRecognizer-Unterklasse erstellt, mit der alle Gestenerkenner blockiert werden können, die an Übersichten einer bestimmten Ansicht angehängt sind.
Es ist Teil meines WEPopover-Projekts. Sie finden es hier .
quelle
Implementieren Sie einen Delegaten für alle Erkenner der übergeordneten Ansicht und fügen Sie die gestureRecognizer-Methode in den Delegaten ein, der für das gleichzeitige Auslösen von Erkennern verantwortlich ist:
}}
Sie können die Fehlermethoden verwenden, wenn Sie möchten, dass die untergeordneten Elemente ausgelöst werden, nicht jedoch die übergeordneten Erkenner:
https://developer.apple.com/reference/uikit/uigesturerecognizerdelegate
quelle
Ich habe auch einen Popover gemacht und so habe ich es gemacht
quelle
Sie können es aus- und wieder einschalten. In meinem Code habe ich so etwas getan, da ich es ausschalten musste, wenn die Tastatur nicht angezeigt wurde. Sie können es auf Ihre Situation anwenden:
Nennen Sie dies viewdidload usw.:
Erstellen Sie dann die beiden Methoden:
Dadurch wird der Wasserhahn deaktiviert. Ich musste tap in eine Instanzvariable verwandeln und sie im Dealloc freigeben.
quelle