Reputation: 402
Alright so in the interface builder (Main.storyboard
), I have a containerView:UIView
embedded in a UIScrollView
. Within in the containerView
I want to create additional UIView
's to hold blocks of content such as a header, body, etc. The reason for doing it like this, is so that the content can scroll vertically but not horizontally.
My goal is to use autolayout to create these different UIView
's. As of right now the containerView automatically adjusts it's width depending on the screen size of the device being used, as to prevent horizontal scrolling. It does this using an IBOutlet I created for the width constraint. It currently looks like so:
@IBOutlet var containerView: UIView!
@IBOutlet var containerViewWidthConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
//Prevents horizontal scrolling
containerViewWidthConstraint.constant = self.view.frame.size.width
createHeader()
}
Then I created a function called createheader{}
which pins a headerView:UIView
at the top of the containerView
, and 8 points from either edge of the containerView
:
func createHeader() {
//Create header
let headerView = UIView()
headerView.backgroundColor = UIColor.blueColor()
self.containerView.addSubview(headerView)
//Create header constraints
let leftMargin = NSLayoutConstraint(item: headerView, attribute: .Leading, relatedBy: .Equal, toItem: containerView, attribute: .Leading, multiplier: 1.0, constant: 8)
let rightMargin = NSLayoutConstraint(item: containerView, attribute: .Trailing, relatedBy: .Equal, toItem: headerView, attribute: .Trailing, multiplier: 1.0, constant: 8)
let topMargin = NSLayoutConstraint(item: headerView, attribute: .Top, relatedBy: .Equal, toItem: containerView, attribute: .Top, multiplier: 1.0, constant: 70)
let heightConstraint = NSLayoutConstraint(item: headerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 160)
//Activate header constraints
headerView.setTranslatesAutoresizingMaskIntoConstraints(false)
NSLayoutConstraint.activateConstraints([leftMargin,rightMargin,topMargin,heightConstraint])
println(headerView.frame.size.width)
}
Now since the size of the content inside the headerView
will be dependent on the screen size of the device being used, I want to be able to create functions that size the width of the content depending on the size of the width of the headerView
itself. However every time I try to grab the width of the headerView
using:
println(headerView.frame.size.width)
It returns a value of zero, which is obviously not the case because it is still creating a blue-background headerView
according to the constraints above.
Why is SWIFT not recognizing that the headerView
has a width? And how can I grab the width of the headerView
?
Upvotes: 2
Views: 3251
Reputation: 9342
After installing constraints you need to call layoutIfNeeded
if you want to update the frames immediately.
func createHeader() {
//Create header
let headerView = UIView()
headerView.backgroundColor = UIColor.blueColor()
self.containerView.addSubview(headerView)
...
//Activate header constraints
headerView.setTranslatesAutoresizingMaskIntoConstraints(false)
NSLayoutConstraint.activateConstraints([leftMargin,rightMargin,topMargin,heightConstraint])
self.containerView.layoutIfNeeded() // Updates the frames
println(headerView.frame.size.width) // Will output the correct width
}
Note that this will happen automatically on the next iteration of the UI loop which is, however, not helpful to you when you want to see the effects immediately.
Upvotes: 3