开发者

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

开发者 https://www.devze.com 2022-12-17 17:42 出处:网络
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.

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 开发者_如何学Godo this?


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);
    }];


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


If you want animating from fontSize to fontSize you can use CATextLayer class

// create text layer 
let textLayer = CATextLayer()
textLayer.font = UIFont.systemFontOfSize(50)
textLayer.fontSize = 50
textLayer.string = "text"
textLayer.foregroundColor = UIColor.redColor().CGColor
textLayer.backgroundColor = UIColor.blackColor().CGColor
textLayer.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
view.layer.addSublayer(textLayer)

// animation
let animation = CABasicAnimation(keyPath: "fontSize")
animation.toValue = 10
animation.duration = 3
textLayer.layer.addAnimation(animation, forKey: nil)


I've just made a solution for this. It's based on CGAffineTransformScale too, but it also has some other tricks up its sleeve and handles all the border cases:

Check it out: https://github.com/ivankovacevic/ARLabel


You can't change the point size of the font, but you can replace the UILabel's font with a new UIFont that uses the new point size you desire.

label.font = [UIFont fontWithName:@"Arial-BoldMT" size:12.0];
// ... some time later
label.font = [UIFont fontWithName:@"Arial-BoldMT" size:14.0];

You'll probably also want to modify the UILabel's frame to accommodate the new point size, especially if you're increasing the point size. Otherwise, your label will get cropped.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号