无法接收以编程方式创建的 UIButton 的触摸事件

unable receive touch events of UIButton created pragrammatically

我创建了一个自定义 UIButton class。单击按钮时,我需要显示(动画)三个按钮,为此我以编程方式创建了三个按钮(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")

    }
}

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

但是,您可以通过将其添加到 ReactionButton class:

来与“动态显示的按钮”进行交互
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
}