问题
A reproducible example
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
}
}
}
Problem
I want to align my custom view to the bottom edge of my UIScrollView
, but I can only seem to align it to the top, or vertical center.
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),
])
But what I want is to have a picture like this. How do I get there?
回答1:
ScrollView with auto layout works differently either you can use only one subview by setting translatesAutoresizingMaskIntoConstraints = true
and setting contentSize explicitly.
Or you set translatesAutoresizingMaskIntoConstraints = false
and let it find out constraint it self.
In your case you can add an invisible view inside scroll and pin it to top and set its height to scrollView.bounds.size.height
and then set create constraint with that invisible view
Change your constraint like this
scrollView.addConstraints([
NSLayoutConstraint(
item: circleContainerView,
attribute: .Bottom,
relatedBy: .Equal,
toItem: invisibleView,
attribute: .Bottom,
multiplier: 1,
constant: 0),
])
Visit this link for more details, read pure auto layout approach
Update: your modified code
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
}
}
}
来源:https://stackoverflow.com/questions/31968547/nslayoutconstraint-that-would-pin-a-view-to-the-bottom-edge-of-a-superview