Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can font size of UILabel be changed with smooth animation on iPhone?

I want a UILabel to swell slightly when selected like in some game menu screens. To get smooth resizing I presume I should put some change to the label's properties in an animation block.

The obvious thing to try is to change the label.font.pointSize property but that's readonly.

Scaling the label's .transform property with CGAffineTransformationMakeScale() makes the text blurry.

Is there some other way to do this?

like image 907
willc2 Avatar asked Jan 20 '10 03:01

willc2


2 Answers

Set the font on the UILabel to be the size that you want when it is enlarged. Then scale it down. When you want the label to swell, scale it back up to it's original size.

    messageLabel.font = [UIFont boldSystemFontOfSize:45]; 
    messageLabel.transform = CGAffineTransformScale(messageLabel.transform, 0.25, 0.25); 
    [self.view addSubview:messageLabel]; 
    [UIView animateWithDuration:1.0 animations:^{
        messageLabel.transform = CGAffineTransformScale(messageLabel.transform, 4, 4);
    }];
like image 169
Bart Whiteley Avatar answered Nov 08 '22 11:11

Bart Whiteley


UPDATED for Xcode 8 / Swift 3 / iOS 10 SDK.

I've created UILabel extension in Swift. Uncomment commented lines if your label is left aligned.

import UIKit

extension UILabel {
    func animateToFont(_ font: UIFont, withDuration duration: TimeInterval) {
        let oldFont = self.font
        self.font = font
        // let oldOrigin = frame.origin
        let labelScale = oldFont!.pointSize / font.pointSize
        let oldTransform = transform
        transform = transform.scaledBy(x: labelScale, y: labelScale)
        // let newOrigin = frame.origin
        // frame.origin = oldOrigin
        setNeedsUpdateConstraints()
        UIView.animate(withDuration: duration) {
        //    self.frame.origin = newOrigin
            self.transform = oldTransform
            self.layoutIfNeeded()
        }
    }
}

Objective-C version:

@interface UILabel(FontAnimation)

- (void) animateToFont:(UIFont*)font withDuration:(NSTimeInterval) duration;

@end

@implementation UILabel(FontAnimation)

- (void) animateToFont:(UIFont*)font withDuration:(NSTimeInterval) duration {
    UIFont * oldFont = self.font;
    self.font = font;
    // CGPoint oldOrigin = self.frame.origin;
    CGFloat labelScale = oldFont.pointSize / font.pointSize;
    CGAffineTransform oldTransform = self.transform;
    self.transform = CGAffineTransformScale(self.transform, labelScale, labelScale);
    // CGPoint newOrigin = self.frame.origin;
    // self.frame = CGRectMake(oldOrigin.x, oldOrigin.y, self.frame.size.width, self.frame.size.height);
    [self setNeedsUpdateConstraints];
    [UIView animateWithDuration:duration animations: ^{
        // self.frame = CGRectMake(newOrigin.x, newOrigin.y, self.frame.size.width, self.frame.size.height);
        self.transform = oldTransform;
        [self layoutIfNeeded];
    }];
}

@end
like image 14
mixel Avatar answered Nov 08 '22 13:11

mixel