子视图中无响应的UIButton添加到UIStackView

时间:2016-08-26 13:19:43

标签: swift uibutton scrollview uistackview

UISplitView的detailViewController中,我将子视图添加到UIStackView内的UIScrollView

只使用没有subviewsimages的系统按钮会产生自适应按钮,但subviews似乎会产生干扰。

启用触摸是专门编码的。我试图将每个视图保留在包含视图中,这样就没有重叠来使接收触摸事件无效,但不确定这是否正确完成。 每个subview都包含一个label和一个带图片的自定义按钮。然后,子视图会添加到stackviewstackview会添加到scrollview

感谢您的帮助。

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")

}

11 个答案:

答案 0 :(得分:18)

我遇到了完全相同的问题:包含视图的StackView。每个视图都包含一个按钮和一个标签。由于布局原因,视图只是容器。

在我的情况下:我没有给视图一个高度约束,似乎它的高度为零(在更改调试后的背景颜色后我没有看到视图),但是按钮和标签是可见的(但是反应迟钝)。

在布局视图中添加了高度约束后,(调试)背景颜色可见,按钮按预期响应。

答案 1 :(得分:4)

似乎有些东西躺在你的按钮上并捕捉所有触摸事件。

<强> 1。如果您不需要,请勿打开userInterectionEnabled

像subView这样的普通视图没有理由将userInteractionEnabled设置为true,因此将其设置为false。

<强> 2。找到错误:

要找出女巫视图捕获事件,请在设备上启动应用程序并导航到stackView。现在在Xcode中,按下按钮&#34; Debug View Hierarchy&#34; (放在控制台输出上方)

enter image description here

之后,您将看到设备上当前显示的每个视图。 你现在做的是发现你的按钮上面有任何视图,然后在代码中将他们的userInteractionEnabled值变为false。

答案 2 :(得分:4)

就我而言,是引起问题的StackView的aligment属性。

当我将该属性设置为Fill而不是Center时,问题消失了。

答案 3 :(得分:2)

我注意到 XCode 12 中的一个错误(我猜)。 当我的 IBOutlet func(在 swift 上)为空时,我在空 func 的主体内或 func 声明本身上放置了一个断点,然后触摸按钮 - XCode 不会在我的断点处停止(在模拟器上测试)。

答案 4 :(得分:1)

在Guy的answer之后,我使用了sherlock app,我立即发现了问题:

enter image description here

答案 5 :(得分:1)

就我而言,这只是Xcode的错误。我刚刚关闭并重新打开了它。它只是工作。我当前的Xcode版本是11.4.1。

答案 6 :(得分:0)

我遇到了同样的问题。原因是我设置button.alpha = 0,同时设置button.layer.opacity = 1.0。在这种情况下,按钮不会响应操作,尽管它是可见的。所以设置button.alpha = 1.0就是答案。可能有帮助!

答案 7 :(得分:0)

就我而言,我在loadView中设置了一个自定义视图子类。该子类具有isUserInteractionEnabled = false,可将其转换为所有子视图,包括我的stackView及其所有视图和按钮。

答案 8 :(得分:0)

我只是自己遇到了这个问题。就我而言,我有一个UIStackView作为UIButton的子视图。我需要在堆栈视图上设置isUserInteractionEnabled = false才能使按钮正常工作。在任何UIButton子视图上设置这可能都是明智的选择。

答案 9 :(得分:0)

对我来说,问题是我正在从情节提要中实例化Stack View的视图,并且未将ViewController添加到视图结构中,但UIView了。这就是为什么UIViewController子类的按钮操作不起作用的原因。因此,https://stackoverflow.com/a/42179529/344386的Mostafa Aghajani的回答对我有所帮助。 如果我做这样的事情:

    let testViewController = storyboard.instantiateViewController(withIdentifier: "TestViewController") as! TestViewController
    
    view.addSubview(testViewController.view) 
    // OR FOR STACK VIEW
    stackView.addArrangedSubview(testViewController.view)

通常,当我检查“ XCode / Debug / View调试/ Capture视图层次结构”时,视图结构看起来像UIViewController / UIView。 但在这种情况下不是。 关键是要这样做:

    let testViewController = storyboard.instantiateViewController(withIdentifier: "TestViewController") as! TestViewController
    self.addChild(testViewController) // this is the key

    view.addSubview(testViewController.view) 
    // OR FOR STACK VIEW
    stackView.addArrangedSubview(testViewController.view)

然后,将UIViewController添加到视图层次结构中,并且我在testViewController内部的UIButton开始起作用。 这就是一种萨满教,也许是我做错了。

答案 10 :(得分:0)

我在我的堆栈视图中发生了这种情况,因为按钮超出了堆栈视图的范围 - 但这在故事板视图中并不明显。要确认这是问题所在,请选择堆栈视图并在属性检查器中打开“剪辑到边界”以查看您的按钮是否从堆栈视图中消失。您可能必须检查父层次结构中的每个堆栈视图,一直到最顶层的堆栈视图。也请在所有手机尺寸上检查这一点 - 在 iPhone 11 上可能适用的可能会夹在 iPhone4s 上。