I am using the following to add a UITextField to a UIStackView. The main issue is the UITextField is expanding to take the complete height. What am I doing wrong? I want UITextField to be of 44 or 60 points height.
lazy var nameTextField: UITextField = {
let textfield = UITextField()
textfield.translatesAutoresizingMaskIntoConstraints = false
textfield.placeholder = "Budget name"
textfield.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 0))
textfield.leftViewMode = .always
textfield.borderStyle = .roundedRect
return textfield
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.green
setupUI()
}
private func setupUI() {
let stackView = UIStackView()
stackView.alignment = .leading
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = UIStackView.spacingUseSystem
stackView.isLayoutMarginsRelativeArrangement = true
stackView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20)
view.addSubview(stackView)
stackView.addArrangedSubview(nameTextField)
// add constraints on nameTextField
nameTextField.widthAnchor.constraint(equalToConstant: 200).isActive = true
nameTextField.heightAnchor.constraint(equalToConstant: 60).isActive = true
// add constraints stackview
stackView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
}
}
A UIStackView arranges its subviews (.addArrangedSubview()).
So, you are telling auto-layout to:
make the text field 60-points tall
AND
make the text field as tall as the stack view
In this case, the stack view wins.
Edit - for clarification...
When you ran your app, you should have seen a bunch of auto-layout error / warning messages. That tells you that you have assigned conflicting constraints.
If you want the text field height to use the .heightAnchor.constraint(equalToConstant: 60) that you've assigned, you have a few options...
1 - Don't embed it in a stack view.
2 - Don't assign a height to the stack view (either directly or with top & bottom constraints).
3 - add additional arrangedSubviews to the stack view.
So, if you make only this change to your code:
stackView.addArrangedSubview(nameTextField)
// comment out this line
//stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
you'll get this:
If you leave that line in, and add a yellow-background UILabel as another arranged subview:
stackView.addArrangedSubview(nameTextField)
// leave this un-commented
stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
let label = UILabel()
label.text = "The Label"
label.backgroundColor = .yellow
label.widthAnchor.constraint(equalToConstant: 200).isActive = true
stackView.addArrangedSubview(label)
you'll get this:
because you gave the text field an explicit Height constraint, so the label height "stretches."
Or, if you add the label and omit the stack view's bottom anchor:
stackView.addArrangedSubview(nameTextField)
// comment out this line
//stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
let label = UILabel()
label.text = "The Label"
label.backgroundColor = .yellow
label.widthAnchor.constraint(equalToConstant: 200).isActive = true
stackView.addArrangedSubview(label)
you'll get this:
because you gave the text field an explicit Height constraint, and let the label use its Intrinsic Content Size.
Related
I made an example ViewController with two Labels to highlight my issue. The goal is to vertically separate the labels by 10, and then center them vertically using greater than or equal to constraints. I'm using visual format, but this should apply if I setup my constraints like view.topAnchor.constraint(greaterThan.... I also have two constraints to horizontally layout the labels
My ViewController:
class myVC: UIViewController {
lazy var titleLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "Hello World"
l.font = .systemFont(ofSize: 50)
l.textColor = .black
return l
}()
lazy var descLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "description"
l.font = .systemFont(ofSize: 35)
l.textColor = .gray
return l
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
view.addSubview(titleLabel)
view.addSubview(descLabel)
titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
descLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor).isActive = true
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|", options: .init(), metrics: nil, views: ["titleLabel": titleLabel, "descLabel": descLabel]))
}
}
This results in . From my understanding, this SHOULD separate the views by 10 pts, and center the labels vertically because in the format "V:|-(<=50)-[titleLabel]-(10)-[descLabel]-(<=50)-|" I say that the distance between the Title Label's top and the superView's top should be at least (greaterThanOrEqualTo) 50, and the distance between the description Label's bottom and the superView's bottom should be at least 50. What should my top and bottom constraints look like if I want to center the two labels vertically?
Yes, I realize I can just set vertical and horizontal centers, but this is an example I made for a problem I can't use those for. I need to be able to center the View with greater(or less) than or equal to constraints.
It's very difficult to center elements using VFL.
It's also difficult to center two elements unless they are embedded in a UIView or a UIStackView.
Here is one option by embedding the labels in a "container" UIView:
class MyVC: UIViewController {
lazy var titleLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "Hello World"
l.font = .systemFont(ofSize: 50)
l.textColor = .black
// center the text in the label - change to .left if desired
l.textAlignment = .center
return l
}()
lazy var descLabel: UILabel = {
let l = UILabel(frame: .zero)
l.translatesAutoresizingMaskIntoConstraints = false
l.text = "description"
l.font = .systemFont(ofSize: 35)
l.textColor = .gray
// center the text in the label - change to .left if desired
l.textAlignment = .center
return l
}()
lazy var containerView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .yellow
// give the labels and containerView background colors to make it easy to see the layout
titleLabel.backgroundColor = .green
descLabel.backgroundColor = .cyan
containerView.backgroundColor = .blue
// add containerView to view
view.addSubview(containerView)
// add labels to containerView
containerView.addSubview(titleLabel)
containerView.addSubview(descLabel)
NSLayoutConstraint.activate([
// constrain titleLabel Top to containerView Top
titleLabel.topAnchor.constraint(equalTo: containerView.topAnchor),
// constrain titleLabel Leading and Trailing to containerView Leading and Trailing
titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
// constrain descLabel Leading and Trailing to containerView Leading and Trailing
descLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
descLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
// constrain descLabel Bottom to containerView Bottom
descLabel.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
// constrain descLabel Top 10-pts from titleLabel Bottom
descLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10.0),
// constrain containerView centered horizontally and vertically
containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
}
Result:
This can be achieved easily by using stackview. Add both the labels in stackview and center it vertically in the superview with all other constraints(top, leading, bottom, trailing).
Here is the sample code of view controller for your use-case.
class ViewController: UIViewController {
lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Hello \nWorld"
label.font = .systemFont(ofSize: 50)
label.backgroundColor = .orange
label.numberOfLines = 0
label.textColor = .black
return label
}()
lazy var descLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "a\n b\n c\n"
label.font = .systemFont(ofSize: 35)
label.backgroundColor = .green
label.numberOfLines = 0
label.textColor = .gray
return label
}()
lazy var contentView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = 10
stackView.distribution = .fill
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
contentView.addArrangedSubview(titleLabel)
contentView.addArrangedSubview(descLabel)
self.view.addSubview(contentView)
let constraints = [
contentView.topAnchor.constraint(greaterThanOrEqualTo: view.safeAreaLayoutGuide.topAnchor),
contentView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
contentView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor)
]
NSLayoutConstraint.activate(constraints)
}
}
The above code will result this view and it goes on to take the top and buttom space until it meets the safeArea. Moreover you can set the vertical content hugging and compression resistance priority to control which label to expand or shrink.
I am using a UIStackView as UITableView's BackGroundView property so when there was an error getting the collection that populates the tableView I can call a function that displays this stack view containing views that show a warning message and a retry button.
I tested doing a similar behaviour in an empty UIViewController so I could center the stackView and its children. The solution worked when I pinned the stack view to the superView's trailing and leading, centered it vertically and set it's top anchor to be greater or equal to the superView's top anchor and similarly it's bottom anchor is greater or equal to the superView's bottom anchor. I have also set the alignment to center and distribution to fill and all seemed to work properly.
Here are some screenshots:
I used this code in a UITableView's extension, but could only reproduce this behaviour. Are there any errors on this code?
func show(error: Bool, withMessage message : String? = nil, andRetryAction retry: (() -> Void)? = nil){
if error{
let iconLabel = UILabel()
iconLabel.GMDIcon = .gmdErrorOutline
iconLabel.textAlignment = .center
iconLabel.numberOfLines = 0
iconLabel.font = iconLabel.font.withSize(50)
iconLabel.textColor = Constants.Colors.ErrorColor
iconLabel.backgroundColor = .blue
let messageLabel = UILabel()
messageLabel.text = message ?? "Ocorreu um erro"
messageLabel.textColor = Constants.Colors.ErrorColor
messageLabel.numberOfLines = 0
messageLabel.textAlignment = .center
messageLabel.font = UIFont(name: "TrebuchetMS", size: 20)
messageLabel.backgroundColor = .green
var views: [UIView] = [iconLabel, messageLabel]
if let retry = retry{
let button = RaisedButton(title: "Tentar novamente")
button.pulseColor = Constants.Colors.PrimaryTextColor
button.backgroundColor = Constants.Colors.PrimaryColor
button.titleColor = .white
button.actionHandle(controlEvents: .touchUpInside, ForAction: retry)
button.contentEdgeInsets = UIEdgeInsetsMake(10,10,10,10)
views.append(button)
}
}else{
self.backgroundView = nil
}
}
let stack = UIStackView()
stack.spacing = 10
stack.axis = .vertical
stack.alignment = .center
stack.distribution = .fill
stack.translatesAutoresizingMaskIntoConstraints = false
for view in views{
view.translatesAutoresizingMaskIntoConstraints = false
stack.addArrangedSubview(view)
}
if self.tableFooterView == nil{
tableFooterView = UIView()
}
self.backgroundView = stack;
if #available(iOS 11, *) {
let guide = self.safeAreaLayoutGuide
stack.topAnchor.constraint(greaterThanOrEqualTo: guide.topAnchor).isActive = true
stack.bottomAnchor.constraint(greaterThanOrEqualTo: guide.bottomAnchor).isActive = true
stack.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
stack.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
stack.centerYAnchor.constraint(equalTo: guide.centerYAnchor).isActive = true
} else {
stack.topAnchor.constraint(greaterThanOrEqualTo: self.topAnchor).isActive = true
stack.bottomAnchor.constraint(greaterThanOrEqualTo: self.bottomAnchor).isActive = true
stack.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
stack.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
stack.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
}
A stack view knows its height if its elements all have an intrinsic size (ie its the sum of their individual heights + the inter item spacing). In this case because you have a 2 y position constraints, you are implying a height, so your constraints are unsatisfiable. The only y axis constraint you need is center vertically. get rid of the top and bottom constraints. The system will then use the intrinsic size to compute the height of the stack view and center it vertically in the background view. Leave your x axis constraints as is.
I have a display of horizontal stack views, which subviews consists on a label and a textField. the stackView is constrained with the borders of the view
I'm trying to stretch my textField subview to so it fills the remaining space of the stack, while the label's stacks adjusts to fit the label size itself. But the inverse is happening. I've tried many solutions but nothing helped me. All the views and constraints we're made programmatically.
For my stack, I'm using:
func customTextField() -> UIStackView {
let stack: UIStackView = {
let sv = UIStackView()
sv.axis = .horizontal
sv.isLayoutMarginsRelativeArrangement = true
sv.alignment = .leading
sv.backgroundColor = .red
sv.translatesAutoresizingMaskIntoConstraints = false
return sv
}()
let label: UILabel = {
let lb = UILabel()
lb.backgroundColor = .red
lb.text = "Label is here"
lb.translatesAutoresizingMaskIntoConstraints = false
return lb
}()
let textField: UITextField = {
let tf = UITextField()
tf.backgroundColor = .blue
tf.text = "Text Field"
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
stack.addArrangedSubview(label)
stack.addArrangedSubview(textField)
return stack
}
the caller of my customTextField:
let profileUserStack: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.spacing = 8
stack.contentMode = .scaleToFill
stack.translatesAutoresizingMaskIntoConstraints = false
return stack
}()
self.addSubview(profileUserStack)
for i in profileTextViews {
let view = self.customTextField()
profileUserStack.addArrangedSubview(view)
}
constraints.append(profileUserStack.buildConstraint(toItem: perfilImageView, constant: 32, type: .top, baseItem: .bottom))
constraints.append(profileUserStack.buildConstraint(toItem: self, constant: 16, type: .leading, baseItem: .leading))
constraints.append(profileUserStack.buildConstraint(toItem: self, constant: -16, type: .trailing, baseItem: .trailing))
activateConstraints(&constraints, to: self)
The results:
https://imgur.com/a/ccFZlRM
Notice that's exactly what I want to achieve. But I want the textField to be stretched.
Set contentHuggingPriority to your label such that it always stays as the size of its content and textField takes remaining space.
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
I have a UIStackView, and as arranged subviews, I have two UIViews, and a UILabel. The UIViews are stacked one after another, while the UILabel is aligned to the leading edge of the subview.
Code:
let stack = UIStackView()
stack.axis = .horizontal
stack.distribution = .fillProportionally
stack.alignment = .center
stack.spacing = 7
view.addSubview(stack)
stack.translatesAutoresizingMaskIntoConstraints = false
stack.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
stack.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
let icon = UIView()
icon.backgroundColor = UIColor.red
stack.addArrangedSubview(icon)
icon.translatesAutoresizingMaskIntoConstraints = false
icon.heightAnchor.constraint(equalToConstant: 42).isActive = true
icon.widthAnchor.constraint(equalToConstant: 42).isActive = true
let icon2 = UIView()
icon2.backgroundColor = UIColor.red
stack.addArrangedSubview(icon2)
icon2.translatesAutoresizingMaskIntoConstraints = false
icon2.heightAnchor.constraint(equalToConstant: 42).isActive = true
icon2.widthAnchor.constraint(equalToConstant: 42).isActive = true
let label = UILabel()
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0
label.sizeToFit()
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .yellow
label.text = "Hello World! Again"
label.textColor = .black
stack.addArrangedSubview(label)
Output:
For clarity...
First, don't use .fillProportionally. Whatever you think that will do, it's wrong. You have explicitly set your two "icons" to be 42-pts wide each. If the stack view is using .fillProportionally, it will try to change the widths of those views, and you will get auto-layout conflicts.
Second, a UILabel with .numberOfLines = 0 must have a width. Otherwise, there is no way to know where to break the text... with a lot of text, it will extend way off the sides of the view.
Third, the line label.sizeToFit() isn't going to accomplish anything here. Just delete it.
If you add this line:
stack.widthAnchor.constraint(equalToConstant: 200.0).isActive = true
then the stack view will expand to 200-pts wide...
Auto-layout will give the first arranged view a width of 42 (because that's what you declared it to be), and the same for the second view. Since you've set the spacing to 7, it will then calculate
42 + 7 + 42 + 7
which equals 98. It subtracts that from the stack view's width:
200 - 98 = 102
and that is the width it will give your label.
Result:
If you don't want to explicitly set the width to 200, you can set it to a percentage of the superview's width, or give it leading and trailing constraints.
Try to change distribution to fill
stack.distribution = .fill
With multiline set
After commenting it
I have added a scrollview subview in one of my views, but am having trouble getting it's height to accurately fit the content that the scrollview is showing, which is text in the UILabel. The height needs to be dynamic (i.e. a factor of the text length), because I am instantiating this view for many different text lengths. Whenever I log label.frame.bounds I get (0,0) back. I have also tried sizeToFits() in a few places without much luck.
My goal is to get the scrollview to end when it reaches the last line of text. Also, I am using only programmatic constraints.
A condensed version of my code is the following:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
let scrollView = UIScrollView()
let containerView = UIView()
let label = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
// This needs to change
scrollView.contentSize = CGSize(width: 375, height: 1000)
scrollView.addSubview(containerView)
view.addSubview(scrollView)
label.text = unknownAmountOfText()
label.backgroundColor = .gray
containerView.isUserInteractionEnabled = true
containerView.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
containerView.frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height)
}
}
Any help is appreciated.
SOLUTION found:
func heightForLabel(text: String, font: UIFont, lineHeight: CGFloat, width: CGFloat) -> CGFloat {
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.setLineHeight(lineHeight: lineHeight)
label.sizeToFit()
return label.frame.height
}
I found this solution online, that gives me what I need to set the appropriate content size for the scrollView height based on the label's height. Ideally, I'd be able to determine this without this function, but for now I'm satisfied.
The key to UIScrollView and its content size is setting your constraints so that the actual content defines the contentSize.
For a simple example: say you have a UIScrollView with width: 200 and height: 200. Now you put a UIView inside it, that has width: 100 and height: 400. The view should scroll up and down, but not left-right. You can constrain the view to 100x400, and then "pin" the top, bottom, left and right to the sides of the scroll view, and AutoLayout will "auto-magically" set the scrollview's contentSize.
When you add subviews that can change size - either explicitly (code, user interaction) or implicitly - if the constraints are set correctly those changes will also "auto-magically" adjust the scrollview's contentSize.
So... here is an example of what you are trying to do:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
let scrollView = UIScrollView()
let label = UILabel()
let s1 = "1. This is the first line of text in the label. It has words and punctuation, but no embedded line-breaks, so what you see here is normal UILabel word-wrapping."
var counter = 1
override func viewDidLoad() {
super.viewDidLoad()
// turn off translatesAutoresizingMaskIntoConstraints, because we're going to set them
scrollView.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
// set background colors, just so we can see the bounding boxes
self.view.backgroundColor = UIColor(red: 1.0, green: 0.7, blue: 0.3, alpha: 1.0)
scrollView.backgroundColor = UIColor(red: 0.8, green: 0.8, blue: 1.0, alpha: 1.0)
label.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
// add the label to the scrollView, and the scrollView to the "main" view
scrollView.addSubview(label)
self.view.addSubview(scrollView)
// set top, left, right constraints on scrollView to
// "main" view + 8.0 padding on each side
scrollView.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 8.0).isActive = true
scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8.0).isActive = true
scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8.0).isActive = true
// set the height constraint on the scrollView to 0.5 * the main view height
scrollView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true
// set top, left, right AND bottom constraints on label to
// scrollView + 8.0 padding on each side
label.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 8.0).isActive = true
label.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 8.0).isActive = true
label.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -8.0).isActive = true
label.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -8.0).isActive = true
// set the width of the label to the width of the scrollView (-16 for 8.0 padding on each side)
label.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -16.0).isActive = true
// configure label: Zero lines + Word Wrapping
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = UIFont.systemFont(ofSize: 17.0)
// set the text of the label
label.text = s1
// ok, we're done... but let's add a button to change the label text, so we
// can "see the magic" happening
let b = UIButton(type: UIButtonType.system)
b.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(b)
b.setTitle("Add a Line", for: .normal)
b.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 24.0).isActive = true
b.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
b.addTarget(self, action: #selector(self.btnTap(_:)), for: .touchUpInside)
}
func btnTap(_ sender: Any) {
if let t = label.text {
counter += 1
label.text = t + "\n\n\(counter). Another line"
}
}
}
give top,left,right and bottom constraint to label with containerView.
and
set label.numberOfLines = 0
also ensure that you have given top, left, right and bottom constraint to containerView. this will solve your issue
Set the auto layout constraints from the interface builder as shown in image .
enter image description here
I set the height of UIScrollView as 0.2 of the UIView
Then drag the UIlabel from MainStoryBoard to the view controller.
Add this two lines in viewdidload method.
draggedlabel.numberOfLines = 0
draggedlabel.lineBreakMode = NSLineBreakMode.byWordWrapping