iosswiftuibuttonsubview

Programmatic UIButton as a subview of UIView is not responding


I'm making a class that extends UITableViewCell--it's going to display a social media newsfeed, with each cell being someone's post.

I've added a UIButton as a subview of a UIView, So the UIView will contain both the button and a label as subviews, like this. (Sorry the image is kind of small but I think you'll get the idea of it).

However, the UIButton isn't responding to taps, not even highlighted. Its superview itself has a number of superviews, all stacks, but I checked and every superview's isUserInteractionEnabled is true.

    let button = UIButton(type: .system)
    button.translatesAutoresizingMaskIntoConstraints = false
    button(UIImage(named: "vertical_dots")?.withRenderingMode(.alwaysOriginal), for: .normal)
    button.backgroundColor = .white
    button.imageView?.contentMode = .scaleAspectFit
    button.addTarget(self, action: #selector(myButtonAction), for: .touchUpInside)
    
    label.text = "\(userPost?.minutesAgo)m"
    label.font = label.font.withSize(11.0)
    label.textColor = .lightGray
    label.translatesAutoresizingMaskIntoConstraints = false
    label.numberOfLines = 1
    
    let superview = UIView()
    superview.translatesAutoresizingMaskIntoConstraints = false
    superview.addSubview(button)
    superview.addSubview(label)
    
    label.leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true
    label.heightAnchor.constraint(equalToConstant: 40).isActive = true
    label.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
    button.leftAnchor.constraint(equalTo: label.rightAnchor).isActive = true
    button.centerYAnchor.constraint(equalTo: superview.centerYAnchor).isActive = true
    button.heightAnchor.constraint(equalToConstant: 20).isActive = true
    button.widthAnchor.constraint(equalToConstant: 15).isActive = true
    

I'm getting a lot of constraint warning but I don't think that would affect things?

Note that this is only a chunk of my code, and I am adding the superview to other views, but I'm not showing all that here. None of my views have frames, only constraints, and they're all appearing correctly.

I don't think this question has been asked before because others are working with Interface Builder, while I'm doing it all programmatically.


Solution

  • Based on the constraints you've shown, you cannot tap your button because it is outside the bounds of your superview.

    To confirm this, add this line:

    superview.clipsToBounds = true
    

    and you almost certainly won't even see your button or label.

    You need to either give superview width and height constraints, or you need to add constraints so the subview(s) determine the superview's bounds.

    For example, add these lines:

        label.topAnchor.constraint(equalTo: superview.topAnchor).isActive = true
        label.bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
        button.rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true