- Fills all spaces
- Default setting
- Uses intrinsic size, but is controlled via CHCR (hugging/compressing)
- Determines which control to stretch by noting which has lowest Content Hugging Priority (CHP)
- If all controls have same CHP, then Xcode will complain layout is ambiguous
- Makes all controls the same size
- Only distribution NOT to use instrinsic size
- maintains same proportion as layout shrinks and grows
- Unlike previous two, needs intrinsic size
- Fill and Fill Equally tell controls how big they should be
- This one is opposite - controls say how big they should be - this just maintains proportions
- Uses intrinsic size
- Maintains equal space between each control
- If ambiguity stack shrinks based on index in
arrangedSubviwes
array
- Equally spaces the center of controls
Those are the distribution options using UIStackView
. Fill and Fill Equally are optionated about controlling size of children. Others respect intrinsic size and try to space in different ways.
This is an example of a fill distribution where normally the two controls we be evenly spaced. But because we want the Internet label to expand we drop its hugging power to 48 so that it will stretch, and then up the hugging power of the text label to 1000. Normally 251 would be OK. But for some reason 1000 is required here making it a required priority constraint.
//
// LabelInAnExpandedStackView.swift
// StackViewFun2
//
// Created by Jonathan Rasmusson Work Pro on 2019-02-23.
// Copyright © 2019 Rasmusson Software Consulting. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
let item1 = makeLabel(title: "Internet", color: .red) // hug = 48 => stretch
let item2 = makeTextField(title: "Ready", color: .green) // hug = 251
let stackView = makeStackView()
stackView.addArrangedSubview(item1)
stackView.addArrangedSubview(item2)
view.addSubview(stackView)
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 48).isActive = true
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8).isActive = true
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8).isActive = true
}
func makeLabel(title: String, color: UIColor) -> UILabel {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = title
label.textAlignment = .center
label.textColor = .black
label.numberOfLines = 0
label.backgroundColor = color
label.setContentHuggingPriority(UILayoutPriority(rawValue: 48), for: .horizontal)
label.setContentHuggingPriority(UILayoutPriority(rawValue: 250), for: .vertical)
return label
}
func makeTextField(title: String, color: UIColor) -> UITextField {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.text = title
textField.backgroundColor = color
// default IB
textField.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .horizontal) // important!
textField.setContentHuggingPriority(UILayoutPriority(rawValue: 250), for: .vertical)
return textField
}
func makeStackView() -> UIStackView {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 8.0
return stackView
}
}