Animating UILabel Font Size Change

I am currently making an application that uses a custom View Controller container. Multiple views are on the screen at one time and when one is tapped, the selected view controller animates to full screen. In doing so, the selected view controllers subviews scale as well (frame, font size, etc.) Though, UILabel’s font property is not animatable leading to issues. I have tried multiple solutions but all flat out suck.

The solutions I have tried are:

  • Objective C: How can you rotate text for UIButton and UILabel?
  • Label display not instant with iPhone app
  • UIView viewwithtag method in swift
  • Problem setting Value for UILabel (iPhone SDK)
  • UITableView with UILabel SizeToFit get mess when Scrolling
  • Xcode: Is there a way to change line spacing (UI Label) in interface builder?
    1. Take a screenshot of the larger view and animating the change (similar to how Flipboard does)
    2. Animate by using the transform property
    3. Zooming out a UIScrollView and zooming it in when brought to full screen.
    4. Setting adjustsFontSizeToFitWidth to YES and setting the fontSize prior to animation

    One has been the best solution so far but I am not satisfied with it.

    I’m looking for other suggestions if anyone has any or a UILabel substitue that animates smoothly using [UIView animate..].

    Here is a good example that is similar to what I would like my UILabel to do:
    http://www.cocoawithlove.com/2010/09/zoomingviewcontroller-to-animate-uiview.html

    EDIT: This code works

    // Load View
    
    self.label = [[UILabel alloc] init];
    self.label.text = @"TEXT";
    self.label.font = [UIFont boldSystemFontOfSize:20.0];
    self.label.backgroundColor = [UIColor clearColor];
    
    [self.label sizeToFit];
    
    [self.view addSubview:self.label];
    
    // Animation
    
    self.label.font = [UIFont boldSystemFontOfSize:80.0];
    self.label.transform = CGAffineTransformScale(self.label.transform, .25, .25);
    [self.label sizeToFit];
    
    [UIView animateWithDuration:1.0 animations:^{
        self.label.transform = CGAffineTransformScale(self.label.transform, 4.0, 4.0);
        self.label.center = self.view.center;
    } completion:^(BOOL finished) {
    
        self.label.font = [UIFont boldSystemFontOfSize:80.0]; 
        self.label.transform = CGAffineTransformScale(self.label.transform, 1.0, 1.0);
    
        [self.label sizeToFit];
    
    }];
    

    5 Solutions Collect From Internet About “Animating UILabel Font Size Change”

    You can change the size and font of your UILabel with animation like bellow .. here I just put the example of how to change the font of UILabel with transform Animation ..

        yourLabel.font = [UIFont boldSystemFontOfSize:35]; // set font size which you want instead of 35
        yourLabel.transform = CGAffineTransformScale(yourLabel.transform, 0.35, 0.35); 
        [UIView animateWithDuration:1.0 animations:^{
            yourLabel.transform = CGAffineTransformScale(yourLabel.transform, 5, 5);
        }];
    

    I hope this helpful to you..

    I’ve created UILabel extension in Swift.

    import UIKit
    
    extension UILabel {
        func animate(font: UIFont, duration: TimeInterval) {
            // let oldFrame = frame
            let labelScale = self.font.pointSize / font.pointSize
            self.font = font
            let oldTransform = transform
            transform = transform.scaledBy(x: labelScale, y: labelScale)
            // let newOrigin = frame.origin
            // frame.origin = oldFrame.origin // only for left aligned text
            // frame.origin = CGPoint(x: oldFrame.origin.x + oldFrame.width - frame.width, y: oldFrame.origin.y) // only for right aligned text
            setNeedsUpdateConstraints()
            UIView.animate(withDuration: duration) {
                //L self.frame.origin = newOrigin
                self.transform = oldTransform
                self.layoutIfNeeded()
            }
        }
    }
    

    Uncomment lines if the label text is left or right aligned.

    You could also use CATextLayer which has fontSize as an animatable property.

    let startFontSize: CGFloat = 20
    let endFontSize: CGFloat = 80
    
    let textLayer = CATextLayer()
    textLayer.string = "yourText"
    textLayer.font = yourLabel.font.fontName as CFTypeRef?
    textLayer.fontSize = startFontSize
    textLayer.foregroundColor = UIColor.black.cgColor
    textLayer.contentsScale = UIScreen.main.scale //for some reason CATextLayer by default only works for 1x screen resolution and needs this line to work properly on 2x, 3x, etc. ...
    textLayer.frame = parentView.bounds
    parentView.layer.addSublayer(textLayer)
    
    //animation:
    let duration: TimeInterval = 1
    textLayer.fontSize = endFontSize //because upon completion of the animation CABasicAnimation resets the animated CALayer to its original state (as opposed to changing its properties to the end state of the animation), setting fontSize to endFontSize right BEFORE the animation starts ensures the fontSize doesn't jump back right after the animation.
    let fontSizeAnimation = CABasicAnimation(keyPath: "fontSize")
    fontSizeAnimation.fromValue = startFontSize
    fontSizeAnimation.toValue = endFontSize
    fontSizeAnimation.duration = duration
    fontSizeAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    textLayer.add(fontSizeAnimation, forKey: nil)
    

    I used it in my project: https://github.com/yinanq/AngelListJobs

    This animation keeps the font top left aligned (unlike CGAffineTransformScale scaling the label from center), pro or con depending on your needs. A disadvantage of CATextLayer is that CALayers don’t work with autolayout constraint animation (which I happened to need and solved it by making a UIView containing just the CATextLayer and animating its constraints).

    Swift 3.0 Update

    UIView.animate(withDuration: 0.5) {
         label.transform = CGAffineTransform(scaleX: 1.1, y: 1.1) //Scale label area
     }
    

    Swift 3.0

     UIView.animate(withDuration: 0.5, delay: 0.1, options: .curveLinear, animations: { 
    
        label.transform = label.transform.scaledBy(x:4,y:4) //Change x,y to get your desired effect. 
    
        } ) { (completed) in
    
             //Animation Completed      
    
        }