2016-12-05 2 views
0

Ich habe ein Overlay mit einer Tabelle in und ich möchte eine Tap Gestenerkennung zum Hintergrund hinzufügen, um die Ansicht zu schließen und auch AddTarget zu einer Schaltfläche innerhalb der Überlagerung, die macht das Gleiche.addTarget und addGestureRecognizer funktioniert nicht, kein Absturz/Fehler

Das Overlay wird wie erwartet angezeigt, jedoch passiert nichts, wenn ich auf den schwarzen Hintergrund oder die Abbrechen-Schaltfläche tippe. Ich habe hier nach einer Antwort gesucht, aber nichts gefunden hat funktioniert. Mein Code ist wie folgt, gefolgt von einem Screenshot der Overlay:

class importedFileView: NSObject { 

let blackView = UIView() 

let importedFileContainerView: UIView = { 
    let importedFileContainerView = UIView(frame: .zero) 
    importedFileContainerView.backgroundColor = .white 
    importedFileContainerView.layer.cornerRadius = 10 
    importedFileContainerView.layer.masksToBounds = true 
    return importedFileContainerView 
}() 

let headerLabel: UILabel = { 
    let headerLabel = UILabel() 
    headerLabel.translatesAutoresizingMaskIntoConstraints = false 
    headerLabel.font = UIFont(name: "HelveticaNeue-Thin" , size: 24) 
    headerLabel.text = "Attach file" 
    headerLabel.textColor = .darkGray 
    headerLabel.adjustsFontSizeToFitWidth = true 
    return headerLabel 
}() 

let fileTableView: UITableView = { 
    let fileTableView = UITableView() 
    return fileTableView 
}() 


let updateDetailsButton: UIButton = { 
    let updateDetailsButton = UIButton() 
    updateDetailsButton.translatesAutoresizingMaskIntoConstraints = false 
    updateDetailsButton.backgroundColor = UIColor(r:40, g:86, b:131) 
    updateDetailsButton.setTitleColor(UIColor.white, for: .normal) 
    updateDetailsButton.setTitle("Attach selected files", for: .normal) 
    updateDetailsButton.titleLabel!.font = UIFont(name: "HelveticaNeue-Light" , size: 18) 
    updateDetailsButton.layer.cornerRadius = 2 
    return updateDetailsButton 
}() 

let cancelButton: UIButton = { 
    let cancelButton = UIButton() 
    cancelButton.translatesAutoresizingMaskIntoConstraints = false 
    cancelButton.backgroundColor = UIColor.white 
    cancelButton.setTitleColor(UIColor(r:40, g:86, b:131), for: .normal) 
    cancelButton.setTitle("Cancel", for: .normal) 
    cancelButton.titleLabel!.font = UIFont(name: "HelveticaNeue-Light" , size: 18) 
    cancelButton.layer.cornerRadius = 2 
    return cancelButton 
}() 

let frameHeight: CGFloat = 450 

func showFormView(){ 

    if let window = UIApplication.shared.keyWindow { 
     blackView.backgroundColor = UIColor(white: 0, alpha: 0.5) 


     window.addSubview(blackView) 
     window.addSubview(importedFileContainerView) 
     importedFileContainerView.addSubview(headerLabel) 
     importedFileContainerView.addSubview(fileTableView) 
     importedFileContainerView.addSubview(updateDetailsButton) 
     importedFileContainerView.addSubview(cancelButton) 

     cancelButton.addTarget(self, action: #selector(handleDismiss), for: .touchUpInside) 
     blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss))) 

     layoutViews() 

     fileTableView.frame = CGRect(x: 30, y: window.frame.height, width: window.frame.width - 60, height: 230) 
     let frameY = (window.frame.height - frameHeight)/2 

     importedFileContainerView.frame = CGRect(x: 20, y: window.frame.height, width: window.frame.width - 40, height: self.frameHeight) 

     blackView.frame = window.frame 
     blackView.alpha = 0 

     UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
      self.blackView.alpha = 1 
      self.importedFileContainerView.frame = CGRect(x: 20, y: frameY, width: window.frame.width - 40, height: self.frameHeight) 
     }, completion: nil 
     ) 
    } 
} 


func layoutViews(){ 
    let views = ["v0" : headerLabel, "v1": fileTableView, "v2": updateDetailsButton, "v3": cancelButton] 

    let leftSpace = NSLayoutConstraint.constraints(withVisualFormat: "H:|-20.0-[v0]-20.0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views) 
    let leftSpace1 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-20.0-[v1]-20.0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views) 
    let leftSpace2 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-20.0-[v2]-20.0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views) 
    let leftSpace3 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-20.0-[v3]-20.0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views) 

    let topSpacing = NSLayoutConstraint.constraints(withVisualFormat: "V:|-20.0-[v0(40)]-20.0-[v1(230)]-20.0-[v2(50)]-10.0-[v3(50)]-10.0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views) 

    importedFileContainerView.addConstraints(topSpacing) 
    importedFileContainerView.addConstraints(leftSpace) 
    importedFileContainerView.addConstraints(leftSpace1) 
    importedFileContainerView.addConstraints(leftSpace2) 
    importedFileContainerView.addConstraints(leftSpace3) 

} 

func handleDismiss() { 

    UIView.animate(withDuration: 0.5, 
        delay: 0.0, 
        options: .curveEaseInOut, 
        animations: { 
        self.blackView.alpha = 0 

        if let window = UIApplication.shared.keyWindow { 
         self.importedFileContainerView.frame = CGRect(x: 20, y: window.frame.height, width: window.frame.width - 40, height: self.frameHeight) 

        } 
    }, 
        completion: { [weak self] finished in 
        self?.blackView.removeFromSuperview() 
        self?.importedFileContainerView.removeFromSuperview() 
    }) 

} 

override init() { 
    super.init() 
} 
} 

enter image description here

Antwort

0

Behalten Sie einen starken Hinweis auf die Instanz Ihrer importedFileView, während Ihre Overlays sichtbar sind? Soweit ich getestet habe, werden alle Aktionen ignoriert, wenn das Ziel verloren geht.

Zum Beispiel funktioniert das nicht:

@IBAction func someAction(_ sender: Any) { 
    let ifv = importedFileView() 
    ifv.showFormView() 

    //`ifv` is released at the end of this method, then your overlays are shown... 
} 

Dies funktioniert:

let ifv = importedFileView() //keep the instance as a property of your ViewController. 
@IBAction func someAction(_ sender: Any) { 
    ifv.showFormView() 
} 

programmatisch erzeugt UIView s isUserInteractionEnabled ist standardmäßig true. Sie müssen es nicht explizit auf true setzen.

Übrigens sollten Sie Ihre nicht-UIView-Klasse besser als ...View bezeichnen und Ihre Typnamen lieber mit Großbuchstaben beginnen, wodurch Ihr Code für erfahrene Swift-Programmierer lesbarer wird.

+0

Bingo! Vielen Dank. Wird die Klasse Swell umbenennen, danke. –

2

self.blackView.isUserInteractionEnabled = true;

alles, was Sie brauchen, ist auf die blackView (UIView) hinzuzufügen.

Ohne diese Option sind in der Ansicht keine Interaktionen aktiviert und daher wird das Ziel/die Aktion des Gestenerkenners nicht ausgelöst.

Ereignisse werden ignoriert.

https://developer.apple.com/reference/uikit/uiview/1622577-isuserinteractionenabled

Vielleicht wollen Sie auch während Animationen deaktivieren.

+0

Ich habe das versucht, aber es hatte keine Wirkung, so dass es wieder entfernt. Ich werde es zurückwerfen und sehen, ob ich etwas sehen kann –

+0

Hinzugefügt es zurück und immer noch nicht funktioniert. Außerdem wurde versucht, addTarget und GestureRecognizer in den Abschlussblock der Animation zu verschieben, um sicherzustellen, dass sie nicht deaktiviert und nicht erneut aktiviert werden. Es wird auch eine Zeile ausgedruckt, um sicherzustellen, dass die Animation fertig ist. –

Verwandte Themen