Skip to content

Instantly share code, notes, and snippets.

@docherty
Created June 17, 2016 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save docherty/b3229cd099472ca3324e3aaf6a6f7330 to your computer and use it in GitHub Desktop.
Save docherty/b3229cd099472ca3324e3aaf6a6f7330 to your computer and use it in GitHub Desktop.
Adjust the size UIView to accommodate the size of its content in Swift
//
// ViewController.swift
// sizingTest
//
// A Swift version of John Erck's SO answer:
// http://stackoverflow.com/a/30511982/131385
//
import UIKit
class ViewController: UIViewController {
var contentView: UIView = UIView()
var myOtherLabel: UILabel = UILabel()
var myLabel: UILabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// INIT ALL REQUIRED UI ELEMENTS
let viewsDictionary = ["contentView": contentView, "myLabel": myLabel, "myOtherLabel": myOtherLabel]
// TURN AUTO LAYOUT ON FOR EACH ONE OF THEM
self.contentView.translatesAutoresizingMaskIntoConstraints = false
self.myLabel.translatesAutoresizingMaskIntoConstraints = false
self.myOtherLabel.translatesAutoresizingMaskIntoConstraints = false
// ESTABLISH VIEW HIERARCHY
self.view.addSubview(self.contentView) // View adds content view
self.contentView.addSubview(self.myLabel) // Content view adds my label (and all other UI... what's added here drives the container height (and width))
self.contentView.addSubview(self.myOtherLabel)
// LAYOUT
// Layout CONTENT VIEW (Pinned to left, top. Note, it expects to get its vertical height (and horizontal width) dynamically based on whatever is placed within).
// Note, if you don't want horizontal width to be driven by content, just pin left AND right to superview.
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]", options:.DirectionLeadingToTrailing, metrics:nil, views:viewsDictionary)) // Only pinned to left, no horizontal width yet
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]", options:.DirectionLeadingToTrailing, metrics:nil, views:viewsDictionary)) // Only pinned to top, no vertical height yet
/* WHATEVER WE ADD NEXT NEEDS TO EXPLICITLY "PUSH OUT ON" THE CONTAINING CONTENT VIEW SO THAT OUR CONTENT DYNAMICALLY DETERMINES THE SIZE OF THE CONTAINING VIEW */
// ^To me this is what's weird... but okay once you understand...
// Layout MY LABEL (Anchor to upper left with default margin, width and height are dynamic based on text, font, etc (i.e. UILabel has an intrinsicContentSize))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[myLabel]", options:.DirectionLeadingToTrailing, metrics:nil, views:viewsDictionary))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[myLabel]", options:.DirectionLeadingToTrailing, metrics:nil, views:viewsDictionary))
// Layout MY OTHER LABEL (Anchored by vertical space to the sibling label that comes before it)
// Note, this is the view that we are choosing to use to drive the height (and width) of our container...
// The LAST "|" character is KEY, it's what drives the WIDTH of contentView (red color)
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[myOtherLabel]-|", options:.DirectionLeadingToTrailing, metrics:nil, views:viewsDictionary))
// Again, the LAST "|" character is KEY, it's what drives the HEIGHT of contentView (red color)
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[myLabel]-[myOtherLabel]-|", options:.DirectionLeadingToTrailing, metrics:nil, views:viewsDictionary))
// COLOR VIEWS
self.view.backgroundColor = UIColor.purpleColor()
self.contentView.backgroundColor = UIColor.redColor()
self.myLabel.backgroundColor = UIColor.orangeColor()
self.myOtherLabel.backgroundColor = UIColor.greenColor()
// CONFIGURE VIEWS
// Configure MY LABEL
self.myLabel.text = "HELLO WORLD\nLine 2\nLine 3, yo"
self.myLabel.numberOfLines = 0; // Let it flow
// Configure MY OTHER LABEL
self.myOtherLabel.text = "My OTHER label... This\nis the UI element I'm\narbitrarily choosing\nto drive the width and height\nof the container (the red view)"
self.myOtherLabel.numberOfLines = 0;
self.myOtherLabel.font = UIFont.systemFontOfSize(21.0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment