繁体   English   中英

UILabel的动画文本更改

[英]Animate Text Change of UILabel

我想为UILabel中的文本更改添加动画效果。

例如:旧文本向上移动,新文本从底部移动。

我已经意识到我需要标签。 一个用于旧的,一个用于新文本。 第二个UILabel位于第一个UILabel下方。 然后两个都动起来了。

但是,你如何切断第一个标签,因为它通过框架的顶部动画?

使用UIView扩展

使用单个标签到位动画:
- 利用内置的CALayer动画和UIView扩展
- 在故事板中,将UILabel放置在带有剪辑子视图标志UIView
- pushTransition适用于大多数UIView

1.扩展

// Usage: insert view.pushTransition right before changing content
extension UIView {
    func pushTransition(_ duration:CFTimeInterval) {
        let animation:CATransition = CATransition()
        animation.timingFunction = CAMediaTimingFunction(name:
            kCAMediaTimingFunctionEaseInEaseOut)
        animation.type = kCATransitionPush
        animation.subtype = kCATransitionFromTop
        animation.duration = duration
        layer.add(animation, forKey: kCATransitionPush)
    }
}

2.调用

if let aLabel = label {
    aLabel.pushTransition(0.4) // Invoke before changing content
    aLabel.text = "\(count)"
    count += 1
}

3.例子

使用kCAMediaTimingFunctionEaseInEaseOut曲线的动画,持续0.4秒,以及kCATransitionFromTop方向

CALayer动画


(†)剪切是实现预期效果的重要步骤。

Swift 2及更早版本,请参阅Steve Baughman的评论:
self.layer.addAnimation(animation, forKey: kCATransitionPush)

►在GitHub上找到此解决方案以及有关Swift Recipes的其他详细信息。

Objective-C的

可以使用Interface Extension在Objective-C中解决Swift UIView Interface Extension

1. Interface Extension

@interface UIView (SO33632266)
- (void)pushTransition:(CFTimeInterval)duration;
@end

@implementation UIView (SO33632266)
// Usage: insert [view pushTransition:]; right before changing content
- (void)pushTransition:(CFTimeInterval)duration
{
    CATransition *animation = [CATransition new];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.type = kCATransitionPush;
    animation.subtype = kCATransitionFromTop;
    animation.duration = duration;
    [self.layer addAnimation:animation forKey:kCATransitionPush];
}
@end

2. pushTransition调用

[aLabel pushTransition:0.4];
aLabel.text = [[NSString alloc] initWithFormat:@"%ld", (long) ++self.count];

3.在行动中

UILabel动画


一次性: 没有接口扩展:

CATransition *animation = [CATransition animation];
animation.timingFunction = [CAMediaTimingFunction
    functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromTop;
animation.duration = 0.4;
[aLabel.layer addAnimation:animation forKey:@"kCATransitionPush"];

调用:

aLabel.text = [[NSString alloc] initWithFormat:@"%ld", (long) ++self.count];

QuartzCore为动画转换操作提供了CATransition类。 CATransition具有以下定义:

CATransition类实现图层的过渡动画。 您可以从一组预定义的转换中指定转换效果,也可以通过提供自定义CIFilter实例来指定转换效果。


为了通过向上推旧文本来CATransition标签的文本转换,您必须创建一个CATransition实例并将其type设置为kCATransitionPush并将其subtypekCATransitionFromTop

let animation = CATransition()
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.type = kCATransitionPush
animation.subtype = kCATransitionFromTop
animation.duration = 1

然后,您可以通过将动画添加到标签的图层来为标签的文本转换设置动画:

label.layer.add(animation, forKey: nil)
label.text = "Some new content"

以下Swift 3 Playground代码显示了一个可能的实现,以便使用CATransitionUILabel的文本转换设置动画:

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {  
    let label: UILabel = {
        $0.frame.origin = CGPoint(x: 50, y: 50)
        $0.text = "Bob"
        $0.sizeToFit()
        return $0
    }(UILabel())
    let animation: CATransition = {
        $0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        $0.type = kCATransitionPush
        $0.subtype = kCATransitionFromTop
        $0.duration = 1
        return $0
    }(CATransition())

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view.addSubview(label)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:)))
        view.addGestureRecognizer(tapGesture)
    }

    func toggle(_ sender: UITapGestureRecognizer) {
        label.layer.add(animation, forKey: nil)
        label.text = label.text == "Bob" ? "Dan" : "Bob"
        label.sizeToFit()
    }
}

let controller = ViewController()
PlaygroundPage.current.liveView = controller

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM