5

I have a UILabel, listDescription, which starts off with 5 lines showing. It is grabbing a large amount of text from a database, and the total number of lines is uncertain. I've implemented a "Show More" button that, when pressed, will expand it to show the whole contents. I've gotten it working fine, however I'm hoping to add an animation for the change in height.

My code:

@IBAction func toggleDesc(sender: AnyObject) {
    if (self.listDescription.numberOfLines>0)
    {
        self.listDescription.numberOfLines=0
        self.showMoreBtn.setTitle("Show Less", forState: UIControlState.Normal)
    }
    else
    {
        self.listDescription.numberOfLines=5
        self.showMoreBtn.setTitle("Show More", forState: UIControlState.Normal)
    }
}

I've tried wrapping the numberOfLines change in UIView.animateWithDuration, but the change was still instantaneous.

My best guess is to put the label in a view, disallow overflow from that view, expand the number of lines, grab the new (unshown) height of the label, and increase the view's size. But then I wouldn't know what to do in the other direction, for shrinking it when "Show less" is tapped.

I'm open for suggestions, and will be doing some experimenting myself.

[Edit: So, I was initially concerned that if I replaced the explicit numberOfLines setting and just introduced a height constraint, the text wouldn't properly truncate at the end (... if it's too long), but it seems to do that just fine.

That said, it would be handy to be able to set the number of lines instead of the height, because I want it to seem consistent across multiple devices, even after I implement automated font-resizing based on the screen dimensions, for tablets and such.

That can be a consideration for later though. I've got a height constraint on the label, and I'm hoping that if I remove the constraint and wrap it in some animation code, it will adjust to its full size. However, I still can't quite get the code right.]

MikeOShay
  • 522
  • 1
  • 7
  • 17
  • 1
    Have a look at this question. It seems as if `numberOfLines` is not animatable. http://stackoverflow.com/questions/20958175/ios-animating-uilabel-expand – Brian Tracy Jan 16 '15 at 05:13
  • Ah. Some of the info there and the ideas behind it definitely help, though the examples/solutions they give seem to be in Objective C and not Swift. – MikeOShay Jan 16 '15 at 21:38
  • I DID learn from this that if a height constraint is given to the label, and the numberOfLines is set to 0, it'll stay at that height and still truncate the tail of the text (if that's the setting in Attributes). So that's one of my concerns out of the way, but there's still the matter of the animation. Right now I'm curious if there's a way to remove the height constraint and animate the adjustment to the proper full height. – MikeOShay Jan 16 '15 at 21:46

1 Answers1

1

You can try a few things, in the animation, use one with options and use .AllowAnimatedContent, also, modify the frame of the label in the animations, for that you will have to calculate the new height based on the text, font, font size and width.

EDIT: Added an extension to calculate the height

extension UIFont {
    func sizeOfString (string: NSString, constrainedToWidth width: Double) -> CGSize {
        return string.boundingRectWithSize(CGSize(width: width, height: DBL_MAX),
            options: NSStringDrawingOptions.UsesLineFragmentOrigin,
            attributes: [NSFontAttributeName: self],
            context: nil).size
    }
}
Juan de la Torre
  • 1,297
  • 9
  • 19
  • Do you know the code I'd need to get the height of the full text? If that's something I can grab dynamically, then the rest of this should just fall together. I've abandoned the "changing the numberOfLines" idea because it seems like there's no real benefit in using that over a height constraint, except possibly some extensibility with auto-resizing for other device dimensions. – MikeOShay Jan 16 '15 at 21:56
  • Check the answer, I added code that you can use to calculate the height of the string – Juan de la Torre Jan 17 '15 at 02:16