Size your view for that “unknown” length string

There are many instances where one needs to obtain string at runtime ( For eg: An API output). This usually means we don’t have no idea how long the string can be ( assuming you don’t own API). Thus arises the predicament, “How do I size my view (uilabel) for a string size that I do not know assuming font size is fixed?”

This post will try to answer this question assuming the view in which you want to render the string as uilabel.

UILabel.lines property 

UILabel.lines is a property on the UILabel view that the users can specify, either via code or via storyboard

Screen Shot 2015-09-19 at 10.55.45 PM

In the above image, we have set a uilabel created on storyboard to have its .lines property value to be 2. This means, if the string assigned to the uilabel requires it, uilabel will wrap to render text in 2 lines. If the string exceeds 2 lines, uilabel truncates string after 2 lines are filled up and appends a triple-dot(…) at the end. Example of truncation is in the image below.

Screen Shot 2015-09-19 at 11.02.02 PM

If we specify 0 here, then the uilabel can take wrap into as many number of lines as required for rendering the string.

Setting UILabel.lines is enough if: 

  • If you know that you have enough space to render uilabel into 2 lines if necessary AND
  • If you don’t need to know the final height of the uilabel after rendering 2 lines for adjustments in your view.  ( If you have designed your constraints correctly the uilabel should just expand and gracefully push down the rest of your view).

If your app’s view requirements are above, then you should be set with the uilabel.lines property. The related property you might be interested in is called uilabel.linebreakmode providing user’s the facility to specify how the string should be truncated

If the above is not enough…

This is where things start getting interesting. Consider the following requirements for your app’s view layout:

  • You need to understand how high the uilabel is in order to adjust the surrounding ui elements accordingly.

In this case, we will make use of the nifty little nsstring method called “sizeWithAttributes” in conjunction with uiview’s “sizeThatFits” method that uilabel inherits from uiview.

sizeWithAttributes method.

This method runs on a string takes an NSDictionary input parameters and returns CGSize object with the recommended size of the uiview which will display the string.

For eg:

let str = “Lets use a very long string. Lets use a very long stringLets use a very long stringLets use a very long stringLets use a very long stringLets use a very long stringLets use a very long stringLets use a very long stringLets use a very long stringLets use a very long string

let size: CGSize = str.sizeWithAttributes([NSFontAttributeName: UIFont.systemFontOfSize(14.0)])

will return the following CGSize object.

Screen Shot 2015-09-20 at 2.29.35 PM

You can find the extensive list of attributes that can be passed into sizeWithAttributes in the Apple documentation here

sizeWithAttributes will return the recommended size that the uiview ( in this case uilabel) should be in order to render the specific string. Remember that this does not take into account the ui constraints and the restrictions applied to the uilabel.

sizeThatFits

In order to figure out the exact size the uiview can take while taking into account the constraints and restrictions present on uiview, we need to use sizeThatFits method. This method takes a CGSize attribute and tries to fit the existing uiview into that size while accounting for the restrictions. If it doesnt fit, this method recommends a new CGSize that the uiview(uilablel) should take. Remember this method does not actually change the frame of the uiview, but only recommends.

Add the below is the code in order to actually update the uilabel frame

        testLabel.frame.size = testLabel.sizeThatFits(size)

        testLabel.text = str

For my project setup of :

  • The storyboard only has one uilabel in it that is vertically and horizontally centered
  • The uilabel has width constraint set to a fixed 100 in the storyboard

The CGSize returned by sizeThatFits is belowScreen Shot 2015-09-20 at 2.43.12 PM

and my uilabel looked like this:

Screen Shot 2015-09-19 at 11.02.02 PMFor a slightly different project setup of  

  • The storyboard only has one uilabel in it that is vertically and horizontally centered
  • The UILabel only has height constraint specified

The uilabel looked like this:

Screen Shot 2015-09-20 at 2.46.08 PM

The UILabel in this case extended beyond the screen bounds, because the constraints did not have any width related restrictions and sizeThatFits tried to fit into the CGSize returned by sizeWithAttributes and hence the rendering.

Size your view for that “unknown” length string

Leave a Reply

Your email address will not be published. Required fields are marked *