无法接收实用创建的UIButton的触摸事件

时间:2020-08-11 08:41:14

标签: ios swift uibutton

我创建了一个自定义UIButton类。单击按钮时,我需要显示(动画)三个按钮,为此,我以编程方式创建了三个按钮(btn1,btn2,btn3),我将所有这三个按钮添加到stackView内并赋予了stackView约束,并将此stackView保留在另一个containerView内(用于背景)按钮的颜色)并以编程方式指定约束。问题是我能够显示和设置容器视图的动画。但是无法接收stackview内按钮的触摸动作,我为按钮添加了目标,但仍然无法在代码中接收到动作的任何问题

class ReactionButton : UIButton
 {
    lazy var btnsMainView : UIView = {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
        view.backgroundColor = .systemGray5
        view.layer.cornerRadius = view.frame.size.height/2
        view.layer.masksToBounds = true
        view.isHidden = true
        return view
    }()
    var btn1 : UIButton = {
        let btn = UIButton(type: .custom)
        btn.backgroundColor = .red
        btn.isUserInteractionEnabled = true
        btn.addTarget(self, action: #selector(btnTapped1), for: .touchUpInside)
        return btn }()
    var btn2 = UIButton(type: .contactAdd)
    var btn3 = UIButton(type: .detailDisclosure)
    
    var leftMainViewAnchor : NSLayoutConstraint?
    var bottomMainViewAnchor : NSLayoutConstraint?
    var widthMainViewAnchor : NSLayoutConstraint?
    var heightMainViewAnchor : NSLayoutConstraint?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
         addStackView()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        addStackView()
        btn2.isUserInteractionEnabled = true
        btn2.addTarget(self, action: #selector(btnTapped1), for: .touchUpInside)
        self.addTarget(self, action: #selector(btnTapped(_:)), for: .touchUpInside)
    }
    
    override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        btnsMainView.isHidden = false
        bottomMainViewAnchor?.constant = -30
        UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
            self.layoutIfNeeded()
        }, completion: nil)
        super.sendAction(action, to: target, for: event)
    }
    
    func addStackView()
    {
        
        self.addSubview(btnsMainView)
        btnsMainView.translatesAutoresizingMaskIntoConstraints = false
        leftMainViewAnchor = btnsMainView.leftAnchor.constraint(equalTo: self.rightAnchor, constant: 0)
        leftMainViewAnchor?.isActive = true
        widthMainViewAnchor = btnsMainView.widthAnchor.constraint(equalToConstant: 100)
        widthMainViewAnchor?.isActive = true
        heightMainViewAnchor = btnsMainView.heightAnchor.constraint(equalToConstant: 30)
        heightMainViewAnchor?.isActive = true
        bottomMainViewAnchor = btnsMainView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0)
        bottomMainViewAnchor?.isActive = true
        
        let stackView = UIStackView(arrangedSubviews: [btn1 , btn2,btn3])
        stackView.distribution = .fillEqually
        stackView.axis = .horizontal
        stackView.alignment = .fill
        stackView.spacing = 2.0
        //stackView.isUserInteractionEnabled = false
        btnsMainView.isUserInteractionEnabled = true
        btnsMainView.addSubview(stackView)
      
        //stackView Constraints
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.leftAnchor.constraint(equalTo: btnsMainView.leftAnchor, constant: 0).isActive = true
        stackView.rightAnchor.constraint(equalTo: btnsMainView.rightAnchor, constant: 0).isActive = true
        stackView.topAnchor.constraint(equalTo: btnsMainView.topAnchor, constant: 0).isActive = true
        stackView.bottomAnchor.constraint(equalTo: btnsMainView.bottomAnchor, constant: 0).isActive = true
    }
    
    @objc func btnTapped(_ sender : UIButton)
    {

    }
    @objc func btnTapped1(_ sender : UIButton)
    {
        print("button tapped1")

    }
}

1 个答案:

答案 0 :(得分:1)

这似乎是一个奇怪的设置...我认为将其作为自定义UIView进行管理会更容易。

不过,您可以通过将其添加到ReactionButton类中来与“动态显示的按钮”进行交互:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // if btnsMainView is hidden, we've tapped on self
    if btnsMainView.isHidden {
        return self
    }
    // loop through subviews, checking hitTest until we find one
    for v in subviews.reversed() {
        let p = v.convert(point, from: self)
        let r = v.hitTest(p, with: event)
        if r != nil {
            return r
        }
    }
    // didn't tap on a subview, so return nil
    return nil
}
相关问题