Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expanding Multiline UILabel

In my iPhone app, I have a multiline label that I would like to expand/contract with a "More" button. Like this:

Lorem ipsum dolor sit amet, consectetur 
adipiscing elit. Donec fringilla, turpis 
in porttitor imperdiet, eros turpis...

                                "<More>"

Should animate into this:

Lorem ipsum dolor sit amet, consectetur 
adipiscing elit. Donec fringilla, turpis 
in porttitor imperdiet, eros turpis laoreet 
magna, id tempor ante lorem pulvinar lacus.
Duis vitae nisl quis sapien dictum pellentesque.

                                "<Less>"

I am trying to get an effect where every line is revealed individually as the label grows, and then individually hidden as it shrinks. Growing works great, but it jumps to 3 lines during the shrink animation. Any ideas? Code and properties below:


Grow animation:

[UIView animateWithDuration:0.5 animations:^{
        view.frame = CGRectMake(startFrame.origin.x, startFrame.origin.y, startFrame.size.width, startFrame.size.height + 40.0);
    }];

Shrink animation:

[UIView animateWithDuration:0.5 animations:^{
        view.frame = CGRectMake(startFrame.origin.x, startFrame.origin.y, startFrame.size.width, startFrame.size.height - 40.0);
    }];

UILabel properties:

  • Lines: 0
  • Line Breaks: Truncate Tail
  • Content Mode: Top
like image 750
user1007895 Avatar asked May 25 '12 21:05

user1007895


1 Answers

You can animate this by using autolayout constraints and modifying the numberOfLines from 3 to 0. (0 is a special value that means show any number of lines).

The label has an intrinsic size that will change when you modify the numberOfLines and those will effect the constraints. The code looks like this:

@IBAction func buttonTapped(sender: UIButton) {
  let numberOfLines = label.numberOfLines == 0 ? 3 : 0
  label.numberOfLines = numberOfLines
  let newTitle = numberOfLines == 0 ? "Less" : "More"    
  sender.setTitle(newTitle, forState: .Normal)
  UIView.animateWithDuration(0.5) { self.view.layoutIfNeeded() }
}

You need to tell the view containing the label and the button that it needs to layout in the animation block.

enter image description here

like image 92
Ray Fix Avatar answered Oct 01 '22 03:10

Ray Fix