Unresponsive UIButton in subview added to UIStackView

Jolly picture Jolly · Aug 26, 2016 · Viewed 12.7k times · Source

In the detailViewController of a UISplitView I have subviews added to a UIStackView inside a UIScrollView.

Just using system buttons without subviews or images, results in responsive buttons, but subviews seem to interfere.

Enabling touch is specifically coded. I have attempted to keep each view inside the containing view so there will be no overlap to invalidate receiving touch events, but not sure if this is done properly. Each subview contains a label and a custom button with an image. The subview is then added to the stackview, and the stackview to the scrollview.

Thanks for any help.

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)

    // Constrain the scroll view within the detailView
    view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))
    view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))


    stackView = UIStackView()

    stackView.frame = CGRectMake(0,0,view.frame.width, 1000)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .Vertical
    scrollView.contentSize = CGSizeMake(400, 1000)
    scrollView.addSubview(stackView)

    // Constrain the stackView within the scrollView
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[stackView]|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))
scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[stackView]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["stackView": stackView]))


    let selectedGroup: Group = GroupArray[5]

    let descriptorsArray = selectedGroup.descriptorsArray

    for descriptor in descriptorsArray {
        // Create a subview for each descriptor

        let subView = UIView()
        subView.frame = CGRectMake(0 , 0, self.stackView.frame.width-10, 54)
        subView.backgroundColor = UIColor.yellowColor()

        subView.heightAnchor.constraintEqualToConstant(54.0).active = true
        // Create a label for Descriptor subview

        let label = UILabel(frame: CGRectMake(20, 0, 200, 50))
        label.text = descriptor.name
        label.font = UIFont.boldSystemFontOfSize(22.0)
        label.textAlignment = .Left
        label.textColor = UIColor.brownColor()
        label.backgroundColor = UIColor.greenColor()
        label.heightAnchor.constraintEqualToConstant(50.0).active = true
        subView.addSubview(label)

        // Create a button for Checkbox
        let btn = UIButton()
        btn.frame = CGRectMake(220, 0, 50, 50)
        btn.backgroundColor = UIColor.blueColor()
        btn.setImage(UIImage(named:"checked.png"), forState: UIControlState.Normal)

        btn.heightAnchor.constraintLessThanOrEqualToConstant(50.0)
        btn.widthAnchor.constraintLessThanOrEqualToConstant(50.0)

        btn.addTarget(self, action: "btnPressed:", forControlEvents: UIControlEvents.TouchUpInside)

        subView.addSubview(btn)
        btn.userInteractionEnabled = true
        subView.userInteractionEnabled = true
        stackView.userInteractionEnabled = true
        scrollView.userInteractionEnabled = true
        stackView.addArrangedSubview(subView)


    }
}

func btnPressed(sender: UIButton!) {

    print("btn Pressed")

}

Answer

theguy picture theguy · Oct 10, 2017

I have had the exact same issue: a StackView which contains views. Each view contains a button and a label. The views are only containers for layout reasons.

In my case: I did not give the view a height constraint and it seems that it had a zero height (after changing the background color for debugging I did not see the view), but the button and label was visible (but unresponsive).

After I have added a height constraint to the layout view the (debug) background color was visible and the buttons responded as expected.