UILabel font resizing animation

I am currently creating an application that uses a special View Controller container. Several views are simultaneously displayed on the screen, and when one of them is used, the selected view controller is animated in full screen mode. At the same time, the selected view controllers also consider the scale (frame, font size, etc.). Although the font property of UILabel is not animated, this leads to problems. I tried several solutions, but all flat suck.

The solutions I tried are as follows:

  • Take a larger screenshot and animate the changes (similar to how Flipboard works)
  • Animation using the transform property
  • Reducing UIScrollView and scaling it when entering in full screen.
  • The setting sets FontSizeToFitWidth to YES and sets fontSize before animation

One of them was the best solution, but I am not satisfied with this.

I am looking for other suggestions if anyone has either a UILabel substitution that animates seamlessly using [UIView animate ..].

Here is a good example that looks like 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]; }]; 
+64
ios iphone uilabel animation
Jan 24 '13 at 5:26
source share
6 answers

You can change the size and font of your UILabel using animation, as shown below. Here I’ll just give an example of how to change the UILabel font using the Animation transform ..

  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 helps you ..

+57
Jan 24 '13 at 5:32
source share

During 2017 ....

Swift 3.0, 4.0

 UIView.animate(withDuration: 0.5) { label.transform = CGAffineTransform(scaleX: 1.1, y: 1.1) //Scale label area } 
+31
May 30 '17 at 10:04
source share

I created the 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() } } } 

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

+21
Sep 09 '16 at 15:35
source share

You can also use CATextLayer, which has fontSize as an animated 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 aligned to the top left (unlike CGAffineTransformScale scaling the label from the center), pro or con depending on your needs. The disadvantage of CATextLayer is that CALayers do not work with animation of autodetection constraints (which I needed and decided by making a UIView containing only CATextLayer and animating its constraints).

+13
Feb 05 '17 at 1:53 on
source share

I created an extension for UILabel to change the font size

 extension UILabel { func animate(fontSize: CGFloat, duration: TimeInterval) { let startTransform = transform let oldFrame = frame var newFrame = oldFrame let scaleRatio = fontSize / font.pointSize newFrame.size.width *= scaleRatio newFrame.size.height *= scaleRatio newFrame.origin.x = oldFrame.origin.x - (newFrame.size.width - oldFrame.size.width) * 0.5 newFrame.origin.y = oldFrame.origin.y - (newFrame.size.height - oldFrame.size.height) * 0.5 frame = newFrame font = font.withSize(fontSize) transform = CGAffineTransform.init(scaleX: 1 / scaleRatio, y: 1 / scaleRatio); layoutIfNeeded() UIView.animate(withDuration: duration, animations: { self.transform = startTransform newFrame = self.frame }) { (Bool) in self.frame = newFrame } } 



If you want to adjust the direction of the animation, use the method below and set a suitable reference point.

SWIFT

 struct LabelAnimateAnchorPoint { // You can add more suitable archon point for your needs static let leadingCenterY = CGPoint.init(x: 0, y: 0.5) static let trailingCenterY = CGPoint.init(x: 1, y: 0.5) static let centerXCenterY = CGPoint.init(x: 0.5, y: 0.5) static let leadingTop = CGPoint.init(x: 0, y: 0) } extension UILabel { func animate(fontSize: CGFloat, duration: TimeInterval, animateAnchorPoint: CGPoint) { let startTransform = transform let oldFrame = frame var newFrame = oldFrame let archorPoint = layer.anchorPoint let scaleRatio = fontSize / font.pointSize layer.anchorPoint = animateAnchorPoint newFrame.size.width *= scaleRatio newFrame.size.height *= scaleRatio newFrame.origin.x = oldFrame.origin.x - (newFrame.size.width - oldFrame.size.width) * animateAnchorPoint.x newFrame.origin.y = oldFrame.origin.y - (newFrame.size.height - oldFrame.size.height) * animateAnchorPoint.y frame = newFrame font = font.withSize(fontSize) transform = CGAffineTransform.init(scaleX: 1 / scaleRatio, y: 1 / scaleRatio); layoutIfNeeded() UIView.animate(withDuration: duration, animations: { self.transform = startTransform newFrame = self.frame }) { (Bool) in self.layer.anchorPoint = archorPoint self.frame = newFrame } } } 

OBJECTIVE-C

 // You can add more suitable archon point for your needs #define kLeadingCenterYAnchorPoint CGPointMake(0.f, .5f) #define kTrailingCenterYAnchorPoint CGPointMake(1.f, .5f) #define kCenterXCenterYAnchorPoint CGPointMake(.5f, .5f) #define kLeadingTopAnchorPoint CGPointMake(0.f, 0.f) @implementation UILabel (FontSizeAnimating) - (void)animateWithFontSize:(CGFloat)fontSize duration:(NSTimeInterval)duration animateAnchorPoint:(CGPoint)animateAnchorPoint { CGAffineTransform startTransform = self.transform; CGRect oldFrame = self.frame; __block CGRect newFrame = oldFrame; CGPoint archorPoint = self.layer.anchorPoint; CGFloat scaleRatio = fontSize / self.font.pointSize; self.layer.anchorPoint = animateAnchorPoint; newFrame.size.width *= scaleRatio; newFrame.size.height *= scaleRatio; newFrame.origin.x = oldFrame.origin.x - (newFrame.size.width - oldFrame.size.width) * animateAnchorPoint.x; newFrame.origin.y = oldFrame.origin.y - (newFrame.size.height - oldFrame.size.height) * animateAnchorPoint.y; self.frame = newFrame; self.font = [self.font fontWithSize:fontSize]; self.transform = CGAffineTransformScale(self.transform, 1.f / scaleRatio, 1.f / scaleRatio); [self layoutIfNeeded]; [UIView animateWithDuration:duration animations:^{ self.transform = startTransform; newFrame = self.frame; } completion:^(BOOL finished) { self.layer.anchorPoint = archorPoint; self.frame = newFrame; }]; } @end 



For example, to change the font size of a label to 30, the duration is 1 s from the center and the scale is longer. Just call

SWIFT

 YOUR_LABEL.animate(fontSize: 30, duration: 1, animateAnchorPoint: LabelAnimateAnchorPoint.centerXCenterY) 

OBJECTIVE-C

 [YOUR_LABEL animateWithFontSize:30 duration:1 animateAnchorPoint:kCenterXCenterYAnchorPoint]; 
+8
Nov 22 '17 at 14:07
source share

Swift 3.0 and Swift 4.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 } 
+4
May 26 '17 at 7:06
source share



All Articles