以编程方式为UIView的子视图设置自动布局约束条件
问题描述:
下面我已经包含了一些代码供您检出。我正在尝试自定义UIView
并为其添加另一个自定义子视图。这个子视图应该被限制在父视图中,它基本上只是在相同的尺寸上放置在顶层,父层只是用作包装。以编程方式为UIView的子视图设置自动布局约束条件
我已经尝试过使用NSLayoutConstraint
,迄今为止失败了。该视图从未真正显示出来。我有一个左侧,右侧,底部和顶部的约束,应该与父视图对齐。
我的第一个问题是,有人请使用下面的方法解释和纠正我的逻辑。我想要的项目参数是您想为(customViewChild
)设置约束的实际视图。该属性是说我希望我的customViewChild
的左边缘用于此约束。 relatedBy
似乎是非常直接的,虽然我可能是错的,然后最后toItem
指向自我这是我的也有.left
属性说,我希望我的孩子和父母的左边排队。这个逻辑是否有缺陷,或者我在做其他的错误?
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
属性不会返回NSLayoutConstraint
。它返回()
。 - 您应该使用
.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
}
}
摆脱customViewChild.addConstraint的'。 ..'。将'isActive'设置为true会将它们添加到正确的视图中。 – vacawama
您是从故事板或笔尖文件创建'CustomViewParent'的实例吗?如果不是那么'init(coder:)'可能没有被调用。使用断点或日志来确认。另外,我建议你使用.leading和.trailing,而不是.left和.right。 – Paulw11