addTarget 和 addGestureRecognizer 不起作用,没有崩溃/错误 [英] addTarget and addGestureRecognizer not working, no crash/error

查看:35
本文介绍了addTarget 和 addGestureRecognizer 不起作用,没有崩溃/错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有表格的覆盖层,我想在背景中添加一个点击手势识别器以关闭视图,并将目标添加到覆盖层中的一个按钮,它执行相同的操作.

I a have an overlay with a table in and I'd like to add a Tap gesture recogniser to the background to dismiss the view and also addTarget to a button within the overlay which does the same thing.

叠加层按预期显示正常,但是每当我点击黑色背景或取消按钮时,什么也没有发生.我在这里搜索了答案,但没有找到任何有效的答案.我的代码如下,后附一张overlay的截图:

The overlay displays fine as expected, however whenever I tap the black background or the cancel button, nothing happens. I've searched for an answer here but nothing found has worked. My code is as follows, followed by a screenshot of the 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()
}
} 

推荐答案

当您的叠加层可见时,您是否保持对 importedFileView 实例的强引用?据我测试,当目标丢失时,所有动作都会被静默忽略.

Are you keeping a strong reference to the instance of your importedFileView while your overlays are visible? As far as I tested, all actions are silently ignored when the target is lost.

例如,这不起作用:

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

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

这有效:

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

<小时>

以编程方式生成的 UIViews isUserInteractionEnabled 默认为 true.您无需将其显式设置为 true.


Programmatically generated UIViews isUserInteractionEnabled is default to true. You have no need to explicitly set it to true.

顺便说一下,你最好不要把你的非UIView类命名为...View,最好让你的类型名称以大写字母开头,使您的代码对于有经验的 Swift 程序员来说更具可读性.

By the way, you'd better not name your non-UIView class as ...View, and better make your type names start with capital letter, which makes your code more readable to experienced Swift programmers.

这篇关于addTarget 和 addGestureRecognizer 不起作用,没有崩溃/错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆