以编程方式将UiView作为子视图放置

时间:2017-11-17 12:44:36

标签: ios swift nslayoutconstraint

我的ViewController看起来像这样。有父ScrollView,它包含UIView(wrapperView),这个包装器视图里面有TextView和ImageView。 这个简单的结构是在界面构建器中创建的,需要所有约束,因此它可以正常工作。

enter image description here

在某些情况下,我需要以编程方式在ImageView中的wrapperView中添加一个UIView(绿色箭头指向那里)。

所以我为我的新UIView创建了xib文件,并为它创建了单独的类

class MyView : UIView {
    class func instanceFromNib() -> UIView {
        return UINib(nibName: "MyView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView
    }
}

我添加了ViewController的代码

let myView = MyView.instanceFromNib()
myView = CGRect(x: 0, y: 0, width: 300, height: 80)
wrapperView.addSubview(myView)

现在我在wrapperView顶部的屏幕上看到myView,但是当我尝试应用

之类的约束时
NSLayoutConstraint(item: myView, attribute: .top, relatedBy: .equal, toItem: myImageView, attribute: .bottom, multiplier: 1.0, constant: 8).isActive = true

我得到了

  

无法同时满足约束

我做错了什么?

3 个答案:

答案 0 :(得分:1)

首先你需要设置它:

myView.translatesAutoresizingMaskIntoConstraints = false

然后你必须确保没有你自己的冲突约束。在故事板中,您可能添加了将imageView.bottomAnchor绑定到wrapperView.bottomAnchor的约束。现在,如果您在这两个锚之间放置另一个视图,则需要停用该约束。

否则,如果你试图在那里挤压myView,可能会导致约束冲突 - 想象一下有一个约束说

  1. imageView.bottomAnchor应该是wrapperView.bottomAnchor的10分,
  2. 但是还有两个限制说

    1. imageView.bottomAnchor应该是myView.topAnchor的10分,myView.bottomAnchor应该是wrapperView.bottomAnchor的10分。
    2. 显然这两种情况都无法满足。

答案 1 :(得分:0)

我认为,最简单的解决方案是将UIStackView添加到界面构建器中的wrapperView,没有高度,只需添加所需的约束(顶部,左侧,底部,右侧)。然后将UIStackView的IBOutlet拖到ViewController中,当您需要添加子视图时:

@IBOutlet weak var stackView: UIStackView!

func someFunc() {
  let myView = MyView.instanceFromNib()
  myView = CGRect(x: 0, y: 0, width: 300, height: 80)
  stackView.addArrangedSubview(myView)
}

UIStackView将根据其子视图更改其大小。

答案 2 :(得分:-1)

您可以使用“调试视图层次结构”来调试UI问题,包括无法满足的约束。很可能在运行时添加的.top约束与您在故事板中设置的.top约束冲突。