2017-11-09 1 views
1

Ich habe eine Ansicht erstellt, die den gesamten Bildschirm überlagert, wenn eine Schaltfläche ausgewählt ist. Insbesondere habe ich eine UIButton in meiner UICollectionViewCell und wenn Sie darauf klicken, rendert es die Überlagerung über das gesamte Fenster des Geräts. Das Overlay ist eine UIView-Hierarchie, wobei UIVisualEffectView die übergeordnete Ansicht des Overlays ist. UIVisualEffectView wird der ViewController.view-Eigenschaft als Unteransicht hinzugefügt, wenn die oben erwähnte UIButton ausgewählt ist.Entfernen von UIView über UITapGestureRecognizer erfordert 2 Klicks (swift)

Ich habe auch eine UITapGestureRecognizer der UIVisualEffectView hinzugefügt. Wenn diese Option ausgewählt ist, sollte das gesamte Overlay entfernt werden, indem die Subviews von ViewController.view entfernt werden.

Das einzige Problem ist das Verhalten des UITapGestureRecognizer. Ich muss zweimal darauf klicken, damit das Overlay verschwindet. Das Hinzufügen von Trace-Print-Anweisungen zeigt, dass die UITapGestureRecognizer-Action #selector-Funktion beim ersten Klick ausgelöst wird, aber erst, wenn ich sie erneut klicke oder auf den Simulatoren-Frame klicke (dh um den Simulator zu bewegen), verschwindet das Overlay richtig. Ich vermute, dass dies mit Threads zu tun haben könnte und Kontrolle zurückgeben könnte, aber ich kann es nicht genau lokalisieren. Unten ist der relevante Code. Jede Hilfe wird geschätzt.

Hinweis: Ich habe dies mit und ohne die removeFromSuperview-Anweisung im DispatchQueue.main.async() - Block ausgeführt; Das Verhalten ist das Gleiche mit und ohne.

-Setup in UIViewController Unterklasse:

var blurBackground = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.dark)) 

blurBackground.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(unblurView)))  

Ziel Aktion, bestätigte über Trace-Anweisungen zu feuern:

func unblurView() { 
    UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
     print("In unblur func") 
     self.blurBackground.alpha = 0.0 

     DispatchQueue.main.async(execute: { 
      self.blurBackground.removeFromSuperview() 
      print("In unblur func - main thread removefromsuperview") 
     }) 

    }, completion: nil) 
} 

Wenn es hilfreich ist, dass ich den Code hinzufügen kann, um bezüglich der Überlagerungsansicht Hinzufügen zu den Viewviews der View-Controller-Ansicht.

Antwort

0

Erstellen einer neuen Single View App-Projekt mit dem folgenden View-Controller funktioniert für mich ganz gut

class ViewController: UIViewController { 

    var blurBackground = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.dark)) 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     blurBackground.frame = self.view.frame 
     blurBackground.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.unblurView))) 
     view.addSubview(blurBackground) 
    } 

    @objc func unblurView() { 
     UIView.animate(withDuration: 0.2, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
      print("In unblur func") 
      self.blurBackground.alpha = 0.0 
      DispatchQueue.main.async(execute: { 
       self.blurBackground.removeFromSuperview() 
       print("In unblur func - main thread removefromsuperview") 
      }) 
     }, completion: nil) 
    } 
} 

wie fügen Sie die blurBackground der Ansicht?

+0

Nach Ihrem Kommentar habe ich versucht, dies auf meinem MBP auszuführen, und es funktioniert. Das Problem war auf meinem Hackintosh - nicht sicher, ob das etwas damit zu tun hat oder nicht. Wirklich seltsam. Obwohl ich glaube, dass animation animiert wird, müssen die Benutzer warten, bis die Animation abgeschlossen ist, bevor TapGesture die Animation beendet. Hört sich das nach dem erwarteten Verhalten an? –

Verwandte Themen