Skip to content

Instantly share code, notes, and snippets.

@yakushevichsv
Created July 31, 2021 09:23
Show Gist options
  • Save yakushevichsv/82e2cbd47a02ac3949702e121cad28b2 to your computer and use it in GitHub Desktop.
Save yakushevichsv/82e2cbd47a02ac3949702e121cad28b2 to your computer and use it in GitHub Desktop.
Kind of vertical stack view & Extensions
import UIView
extension UILabel {
func markAsMultiline() {
numberOfLines = 0
lineBreakMode = .byWordWrapping
}
}
import UIView
// MARK: - UIView + Force
extension UIView {
func forceUpdateConstraint() {
setNeedsUpdateConstraints()
updateConstraints()
}
}
import UIView
// MARK: - VerticalStackView
@IBDesignable final class VerticalStackView: UIView {
private weak var lblTitle: UILabel!
private weak var lblDescr: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setupUI() {
/*guard lblDescr == nil && lblTitle == nil else {
return
}*/
assert(lblTitle == nil)
let lblTitle = UILabel(frame: bounds)
lblTitle.translatesAutoresizingMaskIntoConstraints = false
lblTitle.font = .systemFont(ofSize: UIFont.smallSystemFontSize)
lblTitle.markAsMultiline()
addSubview(lblTitle)
self.lblTitle = lblTitle
assert(lblDescr == nil)
let lblDescr = UILabel(frame: bounds)
lblDescr.translatesAutoresizingMaskIntoConstraints = false
lblDescr.font = .boldSystemFont(ofSize: UIFont.systemFontSize)
lblDescr.markAsMultiline()
addSubview(lblDescr)
self.lblDescr = lblDescr
directionalLayoutMargins = .init(top: 10,
leading: 16,
bottom: 10,
trailing: 16)
//can be compressed...
lblDescr.setContentCompressionResistancePriority(lblTitle.contentCompressionResistancePriority(for: .vertical) - 1,
for: .vertical)
//can be expanded description
lblTitle.setContentHuggingPriority(lblDescr.contentHuggingPriority(for: .vertical) + 1,
for: .vertical)
}
private func setupConstraints() {
/*guard constraints.isEmpty else {
return
}*/
assert(constraints.isEmpty)
let dic: [String : Any] = ["title": lblTitle!,
"desc": lblDescr!]
//position description below title and take into account margins.
let constrs = NSLayoutConstraint.constraints(withVisualFormat: "V:|-[title]-(vSpace)-[desc]-|",
options: .alignAllLeading.union(.alignAllTrailing),
metrics: ["vSpace": directionalLayoutMargins.top],
views: dic)
// title and description have same width..
//full width constraint and margins..
let hConstr = NSLayoutConstraint.constraints(withVisualFormat: "H:|-[title]-|",
metrics: nil,
views: dic)
debugPrint("hConstr \(hConstr)")
NSLayoutConstraint.activate([constrs, hConstr].flatMap { $0 })
}
private func setup(force: Bool = true) {
setupUI()
if force {
forceUpdateConstraint()
} else {
setupConstraints()
}
}
override func updateConstraints() {
super.updateConstraints()
guard constraints.isEmpty else {
return
}
setupConstraints()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
// background to see
backgroundColor = .yellow
lblTitle.backgroundColor = .green
lblDescr.backgroundColor = .blue
//define content
lblTitle.text = "Title Line One \n Line Two" // 2 lines..
lblDescr.text = "Description Line One \n Line Two \n Line Three" // 3 lines..
}
}
@yakushevichsv
Copy link
Author

Create fake XIB (w/o adding to target & see results.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment