2013-04-04 8 views
48

Ich muss eine Funktion implementieren, die einige Code aufrufen wird, wenn ich doppelt auf die self.view tippen (Ansicht UIViewCotroller). Aber das Problem, dass ich andere UI-Objekte in dieser Ansicht habe, und ich möchte kein Erkennungsobjekt an alle anhängen. Ich fand diese Methode unten, wie man aus meiner Sicht eine Geste macht und ich weiß, wie es funktioniert. Gerade jetzt bin ich vor Handicap, welche Art und Weise zu wählen, um diese Erkennung Subview zu ignorieren erstellen. Irgendwelche Ideen? Vielen Dank.UITapGestureRecognizer tippen Sie auf self.view, aber ignorieren Sie Subviews

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)]; 
[doubleTap setNumberOfTapsRequired:2]; 
[self.view addGestureRecognizer:doubleTap]; 
+0

Ich bin nicht sicher, aber haben Sie versucht cancelsTouchesInView auf NO auf die Erkennungs Einstellung? so [doubleTap setCancelsTouchesInView: NEIN]; – JDx

Antwort

85

Sie sollten das UIGestureRecognizerDelegate Protokoll innerhalb des self Objekt und rufen Sie die unten Verfahren zur Überprüfung der Ansicht übernehmen. Innerhalb dieser Methode überprüfen Sie Ihre Ansicht gegen touch.view und geben Sie die entsprechende Bool (Ja/Nein) zurück. Etwas wie das:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    if ([touch.view isDescendantOfView:yourSubView]) { 
     return NO; 
    } 
    return YES; 
} 

Bearbeiten: Bitte überprüfen Sie auch @ Ians Antwort!

+0

noch eine Frage Ich habe einige Tasten auf meiner Ansicht, die funktionieren müssen. Wie kann ich ihnen Priorität geben? –

+0

Wenn Ihre Tasten ihre eigenen Gestenerkenner (wahrscheinlich) haben, graben Sie in ihre Interna und greifen sie, und lesen Sie die Dokumentation auf '- [UIGestureRecognizer requireGestureRecognizerToFail:]' aber es könnte funktionieren, ohne sie zu modifizieren – bshirley

+0

war für Stunden suchen ! Vielen Dank! ;) – MasterRazer

10

Und für die Swift-Variante:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { 
    if touch.view.isDescendantOfView(yourSubView){ 
     return false 
    } 
    return true 
} 

Gut zu wissen, isDescendantOfView gibt einen Boolean Wert, der angibt, ob der Empfänger ein Subview einer bestimmten Ansicht ist oder identisch mit dieser Ansicht.

+1

Vergessen Sie nicht, das UIGestureRecognizerDelegate in Ihrer Klasse zu setzen! – Fox5150

+1

Anstatt dies zu tun, können Sie das nicht einfach zurückgeben? zurück! Touch.view.isDescendant (von: gesticRecognizer.view) Auch neue Syntax in swift 3 ^^ – EdwardSanchez

33

Ein anderer Ansatz besteht darin, einfach zu vergleichen, ob die Ansicht der Berührung die Gestenansicht ist, weil die Nachkommen die Bedingung nicht bestehen. Ein netter, einfacher Einzeiler:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 
    return touch.view == gestureRecognizer.view 
} 
+1

Dies funktioniert besser für mich als die angenommene Antwort. Viel prägnanter. –

+1

@Ian diese Methode wird nicht aufgerufen, wenn Sie auf die Ansicht tippen. – Prabu

+0

Große, präzise Antwort! – scurioni

5

komplette rasche Lösung (Delegierten muss für Erkenner (n) implementiert und eingestellt werden):

class MyViewController: UIViewController UIGestureRecognizerDelegate { 

    override func viewDidLoad() { 
     let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onBaseTapOnly)) 
     doubleTapRecognizer.numberOfTapsRequired = 2 
     doubleTapRecognizer.delegate = self 
     self.view.addGestureRecognizer(doubleTapRecognizer) 
    } 

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { 
     if touch.view.isDescendantOfView(self.view){ 
      return false 
     } 
     return true 
    } 

    func onBaseTapOnly(sender: UITapGestureRecognizer) { 
     if sender.state == .Ended { 
      //react to tap 
     } 
    } 
} 
1

Beachten Sie, dass die gestureRecognizer API geändert hat:

GestenRecognizer (_: shouldReceive :)

Beachten Sie besonders den Unterstrich (Überspringen) für das externe Label des ersten Parameters.

Mit vielen der oben genannten Beispiele erhielt ich das Ereignis nicht. Unten ist ein Beispiel, das für aktuelle Versionen von Swift (3+) funktioniert.

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 
    var shouldReceive = false 
    if let clickedView = touch.view { 
     if clickedView == self.view { 
      shouldReceive = true; 
     } 
    } 
    return shouldReceive 
} 
0

Plus die oben genannten Lösungen, vergessen Sie nicht zu überprüfen User Interaction Enabled Ihrer Unteransicht.

enter image description here

Verwandte Themen