以编程方式将 UiView 放置为子视图
Placing UiView as a subview programmatically
我有 ViewController 看起来像这样。有一个包含 UIView (wrapperView) 的父 ScrollView,这个包装视图内部有 TextView 和 ImageView。
这个简单的结构是从界面构建器创建的,具有所有需要的约束,因此它工作正常。
在某些情况下,我需要以编程方式在 ImageView 正下方的 wrapperView 中再添加一个 UIView(绿色箭头指向那里)。
所以我为我的新 UIView 创建了 xib 文件并为它单独 class
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
我得到了
Unable to simultaneously satisfy constraints
我做错了什么?
您可以使用调试视图层次结构来调试您的 UI 问题,包括未能满足的约束。您在运行时添加的 .top
约束很可能与您在情节提要中设置的 .top
约束冲突。
首先你需要设置这个:
myView.translatesAutoresizingMaskIntoConstraints = false
然后你必须确保没有你自己的约束冲突。在情节提要中,您可能添加了一个将 imageView.bottomAnchor
绑定到 wrapperView.bottomAnchor
的约束。现在,如果您在这两个锚点之间放置另一个视图,则需要停用该约束。
否则,如果您尝试将 myView
挤在那里,可能会导致约束冲突 - 假设有一个约束表示
imageView.bottomAnchor
应该是 wrapperView.bottomAnchor
、 的 10 点
但还有另外两个限制说明
imageView.bottomAnchor
应该是 myView.topAnchor
的 10 分,myView.bottomAnchor
应该是 wrapperView.bottomAnchor
. 的 10 分
显然这两种情况都不能满足。
我认为,最简单的解决方案是在界面构建器中的 wrapperView 中添加一个没有高度的 UIStackView,只需添加所需的约束(顶部、左侧、底部、右侧)。然后将 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 将根据其子视图更改其大小。
我有 ViewController 看起来像这样。有一个包含 UIView (wrapperView) 的父 ScrollView,这个包装视图内部有 TextView 和 ImageView。 这个简单的结构是从界面构建器创建的,具有所有需要的约束,因此它工作正常。
在某些情况下,我需要以编程方式在 ImageView 正下方的 wrapperView 中再添加一个 UIView(绿色箭头指向那里)。
所以我为我的新 UIView 创建了 xib 文件并为它单独 class
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
我得到了
Unable to simultaneously satisfy constraints
我做错了什么?
您可以使用调试视图层次结构来调试您的 UI 问题,包括未能满足的约束。您在运行时添加的 .top
约束很可能与您在情节提要中设置的 .top
约束冲突。
首先你需要设置这个:
myView.translatesAutoresizingMaskIntoConstraints = false
然后你必须确保没有你自己的约束冲突。在情节提要中,您可能添加了一个将 imageView.bottomAnchor
绑定到 wrapperView.bottomAnchor
的约束。现在,如果您在这两个锚点之间放置另一个视图,则需要停用该约束。
否则,如果您尝试将 myView
挤在那里,可能会导致约束冲突 - 假设有一个约束表示
imageView.bottomAnchor
应该是wrapperView.bottomAnchor
、 的 10 点
但还有另外两个限制说明
imageView.bottomAnchor
应该是myView.topAnchor
的 10 分,myView.bottomAnchor
应该是wrapperView.bottomAnchor
. 的 10 分
显然这两种情况都不能满足。
我认为,最简单的解决方案是在界面构建器中的 wrapperView 中添加一个没有高度的 UIStackView,只需添加所需的约束(顶部、左侧、底部、右侧)。然后将 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 将根据其子视图更改其大小。