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

Posted

技术标签:

【中文标题】以编程方式将 UiView 作为子视图【英文标题】:Placing UiView as a subview programmatically 【发布时间】:2017-11-17 12:44:35 【问题描述】:

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

在某些情况下,我需要以编程方式在 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

我明白了

无法同时满足约束

我做错了什么?

【问题讨论】:

您是否将translatesAutoresizingMaskIntoConstraintsmyView 设置为false 添加新视图后需要更新UIScrollView 内容大小。尝试拨打layoutIfNeeded() 【参考方案1】:

首先你需要设置这个:

myView.translatesAutoresizingMaskIntoConstraints = false

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

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

    imageView.bottomAnchor 应该距离wrapperView.bottomAnchor 10 个点,

但还有另外两个限制说明

    imageView.bottomAnchor 应该距离myView.topAnchor 10 个点,myView.bottomAnchor 应该距离wrapperView.bottomAnchor 10 个点。

显然这两种情况都不能满足。

【讨论】:

【参考方案2】:

我认为,最简单的解决方案是将 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 将根据其子视图更改其大小。

【讨论】:

【参考方案3】:

您可以使用调试视图层次结构来调试您的 UI 问题,包括未能满足的约束。很可能您在运行时添加的 .top 约束与您在情节提要中设置的 .top 约束冲突。

【讨论】:

以上是关于以编程方式将 UiView 作为子视图的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将 UIScrollView 滚动到 Swift 中的子 UIView(子视图)的顶部

以编程方式更改子视图控制器

以编程方式使用自动布局实现带有子视图的 uiview 子类

以编程方式在子类 UIView 的子视图上自动布局

swift 以编程方式将UIScrollView滚动到Swift中的子UIView(子视图)的顶部

无法以编程方式将视图添加到情节提要中的现有子视图