Created
July 31, 2021 09:23
-
-
Save yakushevichsv/82e2cbd47a02ac3949702e121cad28b2 to your computer and use it in GitHub Desktop.
Kind of vertical stack view & Extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIView | |
extension UILabel { | |
func markAsMultiline() { | |
numberOfLines = 0 | |
lineBreakMode = .byWordWrapping | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIView | |
// MARK: - UIView + Force | |
extension UIView { | |
func forceUpdateConstraint() { | |
setNeedsUpdateConstraints() | |
updateConstraints() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Create fake XIB (w/o adding to target & see results.)