NSLayoutConstraint 将视图固定到父视图的底部边缘
Posted
技术标签:
【中文标题】NSLayoutConstraint 将视图固定到父视图的底部边缘【英文标题】:NSLayoutConstraint that would pin a view to the bottom edge of a superview 【发布时间】:2015-08-12 14:47:02 【问题描述】:一个可重现的例子
class ViewController: UIViewController
var created = false
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
if !created
let scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.grayColor()
view.addSubview(scrollView)
let kidView = UIView()
kidView.backgroundColor = UIColor.redColor()
kidView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(kidView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
kidView.translatesAutoresizingMaskIntoConstraints = false
view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
)
view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
)
kidView.addConstraints([
NSLayoutConstraint(item: kidView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 100),
NSLayoutConstraint(item: kidView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 100),
])
scrollView.addConstraints([
NSLayoutConstraint(item: kidView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0),
NSLayoutConstraint(item: kidView, attribute: .Bottom, relatedBy: .Equal, toItem: scrollView, attribute: .Bottom, multiplier: 1, constant: 0),
// NSLayoutConstraint(item: kidView, attribute: .CenterY, relatedBy: .Equal, toItem: scrollView, attribute: .CenterY, multiplier: 1, constant: 0),
])
created = true
问题
我想将自定义视图与UIScrollView
的底部边缘对齐,但我似乎只能将其与顶部或垂直中心对齐。
scrollView.addConstraints([
NSLayoutConstraint(
item: circleContainerView,
attribute: .Top,
relatedBy: .Equal,
toItem: scrollView,
attribute: .Top,
multiplier: 1,
constant: 0),
])
scrollView.addConstraints([
NSLayoutConstraint(
item: circleContainerView,
attribute: .CenterY,
relatedBy: .Equal,
toItem: scrollView,
attribute: .CenterY,
multiplier: 1,
constant: 0),
])
但我想要的是有这样一张照片。我怎么去那里?
【问题讨论】:
【参考方案1】:具有自动布局的 ScrollView 的工作方式不同,您可以通过设置 translatesAutoresizingMaskIntoConstraints = true
并显式设置 contentSize 来仅使用一个子视图。
或者你设置translatesAutoresizingMaskIntoConstraints = false
,让它自己找出约束。
在您的情况下,您可以在滚动中添加一个不可见视图并将其固定到顶部并将其高度设置为scrollView.bounds.size.height
,然后使用该不可见视图设置创建约束
像这样改变你的约束
scrollView.addConstraints([
NSLayoutConstraint(
item: circleContainerView,
attribute: .Bottom,
relatedBy: .Equal,
toItem: invisibleView,
attribute: .Bottom,
multiplier: 1,
constant: 0),
])
访问link了解更多详情,阅读纯自动布局方法
更新:您修改后的代码
class ViewController: UIViewController
var created = false
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
if !created
let scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.grayColor()
view.addSubview(scrollView)
let kidView = UIView()
kidView.backgroundColor = UIColor.redColor()
scrollView.addSubview(kidView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
kidView.translatesAutoresizingMaskIntoConstraints = false
scrollView.frame = view.bounds;
scrollView.contentSize = view.bounds.size
// Add an invisible view
let inV = UIView()
inV.backgroundColor = UIColor.clearColor()
inV.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(inV)
view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
)
view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: .AlignAllLeft, metrics: nil, views: ["scrollView": scrollView])
)
var constraint = NSLayoutConstraint(item: inV, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Top, multiplier: 1, constant: 0)
view.addConstraint(constraint)
constraint = NSLayoutConstraint(item: inV, attribute: .Left, relatedBy: .Equal, toItem: scrollView, attribute: .Left, multiplier: 1, constant: 0)
view.addConstraint(constraint)
inV.addConstraints([
NSLayoutConstraint(item: inV, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: 10),
NSLayoutConstraint(item: inV, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 1, constant: self.view.bounds.size.height),
])
//
kidView.addConstraints([
NSLayoutConstraint(item: kidView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .Width, multiplier: 1, constant: 100),
NSLayoutConstraint(item: kidView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 1, constant: 100),
])
view.addConstraints([
NSLayoutConstraint(item: kidView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0),
NSLayoutConstraint(item: kidView, attribute: .Bottom, relatedBy: .Equal, toItem: inV, attribute: .Bottom, multiplier: 1, constant: 0),
])
created = true
【讨论】:
感谢您的输入,但这会将子视图一直向上移动到父视图之上。我已经用完整的代码更新了我的问题以重现这种行为,它只有大约 40 行。 感谢您的更新!考虑到自动布局的工作原理,我现在明白为什么需要额外的视图了。以上是关于NSLayoutConstraint 将视图固定到父视图的底部边缘的主要内容,如果未能解决你的问题,请参考以下文章
NSLayoutConstraint 用于代码中未知数量的子视图
NSLayoutConstraint 将 centerX 约束到 superview 的另一侧
NSLayoutConstraint 用于 UITableView 上的视图