I am trying to find the dynamic height of a UIView at the run time. So, for this I calculated the run time height of UILabels in it and the constraint constants and add them all to get the desired height. But this doesn’t seems to be the correct way of doing it, because in case I alter the count of UILabel or constraints in future then I do have to change the code to calculate the dynamic height. So, is there any way to get the height of UIView at run time with any number of labels and constraints in it?
MY CODE
Here uiview is UIView of which I need to calculate the dynamic height, label1 and label2 are the UILabels in which I inserted text programatically. height is a string extension to find dynamic height of UILabel. label1TopConstraint, label1BottonContraint, label2BottomConstraint are constraints IBOutlets.
let label1Height = label1.text!.height(withConstrainedWidth: label1.frame.width, font: label1.font)
let label2Height = label2.text!.height(withConstrainedWidth: label2.frame.width, font: label2.font)
uiviewHeight = label1Height + label2Height + label1TopConstraint.constant + label1BottonContraint.constant + label2BottomConstraint.constant
3
Answers
Instead of using multiple constraints on multiple labels, you can use UIStackViews vertically or horizontally according to your preference.
Why do you need those runtime calculations if you already use AutoLayout and can rely on constraints? Here’s an example:
A view, containing two labels:
An example usage outcome:
Here’s a view that reuses the first one (among others):
An example usage output:
I think your answer lies in
layoutIfNeeded
and let me explain whyConsider my storyboard set up to set up a Dynamic height UIView which should set its height automatically based on the UILabels within it, note that I did not set the height anchor and so it gives me constraint errors which you can ignore for now as they will be resolved once we are done setting up.
Next I add two labels to this view which have
numberOfLines = 0
Top Label constraints
Bottom Label constraints
After this, the constraint errors go away and notice the height of the view in which the labels are contained in is
82
:Now I add this code which dynamically changes the text in the label
The output is
View height 82.0
which is the value we saw on the storyboard and it is clearly wrong as the view’s height is bigger:So the issue is once you change / update the text, the constraints get updated and the frames will get updated at a later / different iteration of the main run loop which might not be useful to you since you want to do some calculations with it now.
If you want the frames to be updated in the next turn of the update cycle within the main run loop, you need to call
view.setNeedsLayout()
.If you want the frames to be updated immediately, you need to call
view.layoutIfNeeded()
After making this change, the code is as follows:
And now the console displays the correct, updated height: