Saturday 10 January 2015

UIScrollView + UILabel changing label size according to its text content : The power of Autolayout in iOS

The power of Autolayout 

Consider a view with 3 UILabels vertically aligned one by one, from top to bottom in a UIScrollView. These UILabels should adjust its size and layout according to their text contents. Please download the source code attached at the end of this page and open it in XCode. All the contents of the label should be visible on scrolling. Here the following autolayout features can be seen
  • Resizing UILabels according to the text contents
  • Making a scrollable UI which shows those UILabel contents aligned one by one using UIScrollView
  • UILabel Automatically adjusts frame if any UILabel on top / in-between does not have any contents to show
  • All With 0 Coding.  Yes, No coding effort is needed. Everything is done in InterfaceBuilder only !!!
A Good Autolayout design do not show any warnings in the nib file or the storyboard. If it shows, it means the layout may break at runtime causing even an App crash ! 

The big problem with Autolayout and UIScrollView is the warning "Has ambiguous scrollable content height".  example:


Let us see how to overcome this warnings and make a good design in Autolayout ( iOS 7 and above )

1.  Create an XCode project with 'single view application' template and select Universal device from the drop-down

2.  Place a UIScrollView on top of the main UIView and Make the size same as the Parent View. Set the Autolayout Constraint to Top:0, Leading:0,Bottom:0, Trailing:0 with respect to (w.r.t) superview

3. Place a UIView as content view ( please remember this term. this is used in lot of places ) on top of UIScrollView. Make the size of the content view same as the UIScrollView. Set Autolayout Constraint to Top:0, Leading:0,Bottom:0,Trailing w.r.t UIScrollView. As shown in the figure select the View and its parent UIScrollView together and apply "widths equally" constraint.

          
          This is to avoid Horizontal Scrolling and to prevent UILabels from growing towards two sides and get its contents hidden. 

In the same way as shown below set "heights equally" constraint as shown

Select this constraint and don't forget to check its "Remove at build time" option, since we want to make the content view grow in height according to the size of its children 


Now the warning  

will disappear. 

4.  Place 3 UILabels one by one vertically aligned. Set different font colours and font sizes to them. Set constraints as shown below

Top UILabel (name it as topicLabel): leading:20, top:20, trailing:20, height > 1 ( ** this is very important since it helps the autolayout to handle hiding the UILabel for empty contents and adjusts rest of the UILabel frames and alignments automatically ) w.r.t superview

Middle UILabel (name it as descriptionLabel) : leading:20, top:10 ( margin between upper label and current label), trailing:20, height > 1 all w.r.t superview

Bottom UILabel (name it as bottomLabel): leading:20, top:10, trailing:20, height >1, bottom >= 30 ( To create a margin between the bottom most UILabel and its superview )

In the sample code there are 3 outlets for those labels to push some texts programmatically as shown in the method below

-(void)setAllTexts
{
    [self.topicLabel setText:@"Autolayout iOS : Tutorial with Sample Code !!!"];
    [self.descriptionLabel setText:@"This sample code demonstrates how to use variable content UILabels can be used inside a UIScrollView that is scrollable"];
    [self.bottomLabel setText:@"This is Bottom Label. An Offset is set to the bottom of my superview !"];
}

Run the Sample App "Scroll" and feel the power of autolayout. As per the given settings a scrollable colourful label contents layout with proper margins and separations will be displayed. Please try commenting any line / lines in the given method in random and run the code to see how the labels adapts to size and margins !

Example:

 -(void)setAllTexts
{
    [self.topicLabel setText:@"Autolayout iOS : Tutorial with Sample Code !!!"];
    //[self.descriptionLabel setText:@"This sample code demonstrates how to use variable content UILabels can be used inside a UIScrollView that is scrollable"];
    [self.bottomLabel setText:@"This is Bottom Label. An Offset is set to the bottom of my superview !"];
}

iPhone Screenshots attached:

1. All the labels with text contents (scrollview scrolled to middle)



2. Only Top and Bottom labels are set with text contents

case : 

 -(void)setAllTexts
{
    [self.topicLabel setText:@"Autolayout iOS : Tutorial with Sample Code !!!"];
    //[self.descriptionLabel setText:@"This sample code demonstrates how to use variable content UILabels can be used inside a UIScrollView that is scrollable"];
    [self.bottomLabel setText:@"This is Bottom Label. An Offset is set to the bottom of my superview !"];
}

Click here to download sourcecode !

Design UI with AutoLayout and avoid/reduce UI coding !