Search code examples
iosswiftautolayoutuistackview

Button in UIStackView not clickable


I'm trying to add a button to my stack view. The button has a buttonTapped method that should be called when it is tapped. The problem is it is never being called, the button does not seem to be clickable.

class CustomButton: UIViewController {
    var buttonDelegate: ButtonDelegate?

    let button = UIButton(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width - 40, height: 30))
    
    init(label: String) {
        button.setTitle(label, for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .systemBlue
        super.init(nibName: nil, bundle: nil)
    }
    
    @objc func buttonTapped() {
        print("this never gets printed")
        buttonDelegate?.buttonTapped(buttonType: .submit)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        view.addSubview(button)
    }
}

And then my main view controller:

protocol ButtonDelegate {
    func buttonTapped(buttonType: ButtonType)
}

class DynamicViewController: UIViewController, ButtonDelegate {
    lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()

    lazy var stackView: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .equalSpacing
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        return stackView
    }()


    lazy var contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    private func setupViews() {
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(stackView)
        
        let btn = CustomButton(label: "hi")
        btn.buttonDelegate = self
        self.stackView.addArrangedSubview(btn.view)
    }

    func buttonTapped(buttonType: ButtonType) {
        print("also never gets printed")
    }
}

There is nothing overlapping the button or anything like that: enter image description here

My question is why the button is not clickable.


Solution

  • You are adding the view controller as a subview. So you also need to add as a child. Add bellow code after self.stackView.addArrangedSubview(btn.view) this line.

    self.addChild(btn)
    btn.didMove(toParent: self)