SO füge ich einer Overlay-Ansicht einen Gestenerkenner hinzu. Wenn Sie auf dem Bildschirm tippen, möchte ich, dass diese Überlagerung entfernt wird. Das Hinzufügen eines Gestenerkenners setzt jedoch das "Touchup inside" und andere Klickereignisse außer Kraft. Ich brauche das zurück, deshalb muss ich den Erkenner entfernen. Ich kann diese Methode verwenden, aber ich habe ein Problem. Mein Code unten -
- (void)helpClicked
{
CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
[helpOverlay setImage:helpImage];
helpOverlay.tag = 50;
self.scrollEnabled = NO;
[self addSubview:helpOverlay];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
Hier entferne ich die Überlagerung von der anderen Ansicht.
- (void) dismissView
{
UIView *overlay = [self viewWithTag:50];
[overlay removeFromSuperview];
self.scrollEnabled = YES;
}
Meine Frage ist, wie entferne ich die Gestenerkennung in der zweiten Methode? Ich kann den variablen Abgriff dieser Methode nicht übergeben, noch kann ich sie in der vorherigen Methode entfernen. Irgendwelche Hinweise? Ich bin mit ziemlich vielen veränderlichen Problemen geblieben, wenn es um Ereignisse geht.
Aus den WWDC 2015, Cocoa Touch Best Practices wird empfohlen, dass Sie eine Eigenschaft oder eine iVar behalten, wenn Sie später darauf zugreifen müssen, und verwenden Sie nicht viewWithTag:
.
Dies erspart Ihnen einige Probleme:
(d. h.) Sie haben es zum ersten Mal mit Tags implementiert, und alles funktioniert wie erwartet. Später arbeiten Sie an einer anderen Funktionalität, die sagen lässt bricht dies und verursacht unerwünschtes Verhalten, das Sie nicht erwarten. Log gibt keine Warnung aus und das Beste, was Sie je nach Fall bekommen können, ist ein Absturz, der nicht erkannte Selektoren an Instanz sendet. Manchmal bekommst du keine davon.
Deklarieren Sie den iVar
@implementation YourController {
UITapGestureRecognizer *tap;
}
Richten Sie Ihre Ansicht ein
- (void) helpClicked {
//Your customization code
//Adding tap gesture
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
Entfernen Sie die Geste direkt
- (void) dismissView {
[self.view removeGestureRecognizer:tap];
}
Diese Schleife entfernt alle Gestenerkenner einer Ansicht
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self.view removeGestureRecognizer:recognizer];
}
Deklarieren Sie eine ivar
UITapGestureRecognizer *tap
in Ihrem @interface
.
Ändern Sie helpClicked
in:
- (void)helpClicked
{
CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
[helpOverlay setImage:helpImage];
helpOverlay.tag = 50;
self.scrollEnabled = NO;
[self addSubview:helpOverlay];
tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
und dismissView
zu:
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self removeGestureRecognizer:tap];
}
EDIT: Ich denke, die Methode von Nhahtdh ist etwas eleganter im Vergleich zu dieser.
EDIT2: Es scheint, dass Sie [self addGestureRecognizer:tap]
arbeiten, also bin ich der Ansicht, dass dies eine Unterklasse von UIView
ist.
Swift Version:
if let recognizers = yourView.gestureRecognizers {
for recognizer in recognizers {
yourView.removeGestureRecognizer(recognizer)
}
}
Richten Sie die Überlagerungsansicht einfach einmal mit der Gestenerkennung ein, aber machen Sie die Überlagerungsansicht hidden . Wenn eine Ansicht ausgeblendet ist, erhält sie keine Berührung vom Benutzer. Machen Sie die Überlagerungsansicht nur sichtbar, wenn dies erforderlich ist, und machen Sie sie verborgen, wenn Sie sie nicht benötigen.
Ihr Code sollte für die zweite Methode wahrscheinlich eher so aussehen:
- (void) dismissView {
UIView *overlay = [self viewWithTag:50];
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
if([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
[self removeGestureRecognizer:recognizer];
}
}
[overlay removeFromSuperview];
self.scrollEnabled = YES;
}
Ich habe die Prüfung für UITapGestureRecognizer
hinzugefügt, falls Ihre Klasse mehr als 1 UIGestureRecognizer
s verarbeitet und Sie dies nur entfernen möchten.
Diese Arbeit für mich:
for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
[self.view removeGestureRecognizer:gr];
}
In Swift 4
if let gestures = shotButton.gestureRecognizers //first be safe if gestures are there
{
for gesture in gestures //get one by one
{
shotButton.removeGestureRecognizer(gesture) //remove gesture one by one
}
}
Wenn Sie die Ansicht erweitern können, versuchen Sie es folgendermaßen:
_ = gestureRecognizers.flatMap { $0.map { removeGestureRecognizer($0) } }
Es hat für mich funktioniert.
while (view.gestureRecognizers.count) {
[view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}