以编程方式为 UIView 子视图设置自动布局约束
Programatically setting auto layout constraints for a UIView's subviews
下面我提供了一些代码供您查看。我正在尝试采用自定义 UIView
并向其添加另一个自定义子视图。这个子视图应该被限制在 parent 视图中,这样它基本上只是以相同的尺寸放在顶部,而 parent 只是作为一个包装器。
我尝试过使用NSLayoutConstraint
,但到目前为止失败得很惨。该视图从未真正显示出来。我有一个左、右、下和上约束,它们应该与 parent 视图对齐。
我的第一个问题是有人在使用以下方法时请解释或纠正我的逻辑。我认为的项目参数是您要为其设置约束的实际视图 (customViewChild
)。该属性是说我希望 customViewChild
的左边缘用于此约束。 relatedBy
看起来很简单,尽管我可能是错的,最后 toItem
指向 self,这是我的 CustomViewParent
,它也有一个 .left
属性来表示我希望我的 child 和 parent 的左边缘对齐。这个逻辑有问题还是我做错了什么?
NSLayoutConstraint(item: customViewChild!,
attribute: .left,
relatedBy: .equal,
toItem: self,
attribute: .left,
multiplier: 1.0,
constant: 0.0)
我知道下面的例子可以很容易地用 IB 完成,但我试图理解 NSLayoutConstraint
,所以请提供有关的答案。最后,如果有人真的可以更正这段代码,那么我就有了一个工作示例,那就太棒了。
class CustomViewParent: UIView {
var customViewChild: UIView?
override init(frame: CGRect) {
super.init(frame: frame)
setConstraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setConstraints()
}
func setConstraints() {
customViewChild = UIView()
addSubview(customViewChild!)
customViewChild?.translatesAutoresizingMaskIntoConstraints = false
let leftConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .left,
relatedBy: .equal,
toItem: self,
attribute: .left,
multiplier: 1.0,
constant: 0.0).isActive = true
let rightConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .right,
relatedBy: .equal,
toItem: self,
attribute: .right,
multiplier: 1.0,
constant: 0.0).isActive = true
let topConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: 0.0).isActive = true
let bottomConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: 0.0).isActive = true
customViewChild.addConstraint([leftConstraint, rightConstraint, topConstraint, bottomConstraint]);
}
}
三件事:
- 您不需要使用
addConstraint
。只需将约束的 isActive
设置为 true
。
- 同时将
isActive
设置为 true
并将其结果分配给常量是没有意义的。设置 isActive
属性 不会 return NSLayoutConstraint
。它 returns ()
.
- 您应该使用
.leading
和 .trailing
而不是 .left
和 .right
。
进行这些更改后,以下内容应该会起作用:
func setConstraints() {
customViewChild = UIView()
addSubview(customViewChild!)
customViewChild?.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: customViewChild!,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: customViewChild!,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: customViewChild!,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: customViewChild!,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: 0.0).isActive = true
}
您可能会发现这更容易一些,也更易读...
func setConstraints() {
if customViewChild == nil {
customViewChild = UIView()
addSubview(customViewChild!)
customViewChild?.translatesAutoresizingMaskIntoConstraints = false
customViewChild?.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
customViewChild?.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
customViewChild?.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
customViewChild?.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
}
下面我提供了一些代码供您查看。我正在尝试采用自定义 UIView
并向其添加另一个自定义子视图。这个子视图应该被限制在 parent 视图中,这样它基本上只是以相同的尺寸放在顶部,而 parent 只是作为一个包装器。
我尝试过使用NSLayoutConstraint
,但到目前为止失败得很惨。该视图从未真正显示出来。我有一个左、右、下和上约束,它们应该与 parent 视图对齐。
我的第一个问题是有人在使用以下方法时请解释或纠正我的逻辑。我认为的项目参数是您要为其设置约束的实际视图 (customViewChild
)。该属性是说我希望 customViewChild
的左边缘用于此约束。 relatedBy
看起来很简单,尽管我可能是错的,最后 toItem
指向 self,这是我的 CustomViewParent
,它也有一个 .left
属性来表示我希望我的 child 和 parent 的左边缘对齐。这个逻辑有问题还是我做错了什么?
NSLayoutConstraint(item: customViewChild!,
attribute: .left,
relatedBy: .equal,
toItem: self,
attribute: .left,
multiplier: 1.0,
constant: 0.0)
我知道下面的例子可以很容易地用 IB 完成,但我试图理解 NSLayoutConstraint
,所以请提供有关的答案。最后,如果有人真的可以更正这段代码,那么我就有了一个工作示例,那就太棒了。
class CustomViewParent: UIView {
var customViewChild: UIView?
override init(frame: CGRect) {
super.init(frame: frame)
setConstraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setConstraints()
}
func setConstraints() {
customViewChild = UIView()
addSubview(customViewChild!)
customViewChild?.translatesAutoresizingMaskIntoConstraints = false
let leftConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .left,
relatedBy: .equal,
toItem: self,
attribute: .left,
multiplier: 1.0,
constant: 0.0).isActive = true
let rightConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .right,
relatedBy: .equal,
toItem: self,
attribute: .right,
multiplier: 1.0,
constant: 0.0).isActive = true
let topConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: 0.0).isActive = true
let bottomConstraint = NSLayoutConstraint(item: customViewChild!,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: 0.0).isActive = true
customViewChild.addConstraint([leftConstraint, rightConstraint, topConstraint, bottomConstraint]);
}
}
三件事:
- 您不需要使用
addConstraint
。只需将约束的isActive
设置为true
。 - 同时将
isActive
设置为true
并将其结果分配给常量是没有意义的。设置isActive
属性 不会 returnNSLayoutConstraint
。它 returns()
. - 您应该使用
.leading
和.trailing
而不是.left
和.right
。
进行这些更改后,以下内容应该会起作用:
func setConstraints() {
customViewChild = UIView()
addSubview(customViewChild!)
customViewChild?.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: customViewChild!,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: customViewChild!,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: customViewChild!,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: customViewChild!,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: 0.0).isActive = true
}
您可能会发现这更容易一些,也更易读...
func setConstraints() {
if customViewChild == nil {
customViewChild = UIView()
addSubview(customViewChild!)
customViewChild?.translatesAutoresizingMaskIntoConstraints = false
customViewChild?.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
customViewChild?.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
customViewChild?.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
customViewChild?.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
}