【问题标题】:Can font size of UILabel be changed with smooth animation on iPhone?UILabel 的字体大小可以通过 iPhone 上的流畅动画来更改吗?
【发布时间】:2011-01-07 02:52:42
【问题描述】:

我希望 UILabel 像在某些游戏菜单屏幕中那样被选中时略微膨胀。为了平滑调整大小,我认为我应该在动画块中对标签的属性进行一些更改。

显而易见的尝试是更改 label.font.pointSize 属性,但这是只读的。

使用 CGAffineTransformationMakeScale() 缩放标签的 .transform 属性会使文本变得模糊。

还有其他方法可以做到这一点吗?

【问题讨论】:

    标签: iphone-sdk-3.0 uikit uilabel


    【解决方案1】:

    更新适用于 Xcode 8 / Swift 3 / iOS 10 SDK。

    我在 Swift 中创建了 UILabel 扩展。如果您的标签左对齐,请取消注释注释行。

    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 版本:

    @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
    

    【讨论】:

    • 这太棒了,但请务必取消注释 let oldTransform = transform,因为您在动画中使用它而无需声明。
    • @Ahmad Thx,已修复。很高兴为您提供帮助!
    • 您能否将 obj-c 版本添加到您的答案中?
    【解决方案2】:

    如果你想从 fontSize 动画到 fontSize 你可以使用 CATextLayer 类

    // 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)
    

    【讨论】:

      【解决方案3】:

      我刚刚为此制定了解决方案。它也是基于 CGAffineTransformScale 的,但它还有一些其他技巧可以处理所有边界情况:

      检查一下: https://github.com/ivankovacevic/ARLabel

      【讨论】:

        【解决方案4】:

        将 UILabel 上的字体设置为放大时所需的大小。然后按比例缩小。当您希望标签膨胀时,将其缩放回原来的大小。

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

        【讨论】:

        • @Vishal,要恢复它我想你可以等待完成(你可以传递一个回调块来获得通知)然后开始另一个动画。
        • 这实际上是缩放标签,这意味着您应该将初始字体大小设置为尽可能大,然后再缩小;如果你放大,你会看到像素化的文字。
        【解决方案5】:

        您无法更改字体的磅值,但可以将 UILabel 的字体替换为使用所需新磅值的新 UIFont。

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

        您可能还需要修改 UILabel 的框架以适应新的磅值,尤其是在您增加磅值时。否则,您的标签将被裁剪。

        【讨论】:

        • 不是单独的。使用您已经提到的转换缩放 UILabel,一旦动画完成,将较大的 UIFont 分配给 UILabel。这应该会给您在移动 Safari 中放大和缩小时看到的相同效果。在捏合/缩放过程中,文本略微模糊,但一旦手势完成,文本将使用与当前缩放级别匹配的不同字体大小呈现。
        猜你喜欢
        • 1970-01-01
        • 2013-06-24
        • 2012-07-23
        • 2017-08-30
        • 1970-01-01
        • 2011-06-19
        • 2010-12-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多