I\'ve seen answers to vertical resizing that involve autolayout, but the UILabels I\'m creating are only needed at runtime. (I might need anywhere from zero to many
There are two usefull methods of UIView: sizeToFit() and sizeThatFits(_:)
The first one resizes a view to a minimal size to fit subviews' content and the second one doesn't change frame at all, but returns calculated size which: (1) fit all subviews and (2) doesn't exceed parameter size
So you can use sizeThatFits for you purpose:
let label = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
label.backgroundColor = UIColor.orange
label.textColor = UIColor.white
// label.text = "ultimate Frisbee"
label.text = "ultimate Frisbee\nin 3 minutes,\nall welcome|2"
label.numberOfLines = 10
view.addSubview(label)
updateLabelFrame()
}
func updateLabelFrame() {
let maxSize = CGSize(width: 150, height: 300)
let size = label.sizeThatFits(maxSize)
label.frame = CGRect(origin: CGPoint(x: 100, y: 100), size: size)
}
Output:
P.S. You also can solve your problem with autolayout constraints, but I am not a big fan of using them programmatically.