简体   繁体   English

UILabel的动画文本更改

[英]Animate Text Change of UILabel

I want to animate text changes in a UILabel. 我想为UILabel中的文本更改添加动画效果。

For example: old text moves up and new text moves in from the bottom. 例如:旧文本向上移动,新文本从底部移动。

I already realised that I would need to labels. 我已经意识到我需要标签。 One for the old and one for the new text. 一个用于旧的,一个用于新文本。 The second UILabel is located below the first. 第二个UILabel位于第一个UILabel下方。 Then both animate up. 然后两个都动起来了。

However, how do you cut off the first label as it animates past the top portion of the frame? 但是,你如何切断第一个标签,因为它通过框架的顶部动画?

Use a UIView Extension 使用UIView扩展

Animate in place using a single label: 使用单个标签到位动画:
- Leverage upon the built-in CALayer animations, and a UIView extension - 利用内置的CALayer动画和UIView扩展
- In the Storyboard, place the UILabel inside a UIView with Clip Subviews flag . - 在故事板中,将UILabel放置在带有剪辑子视图标志UIView
- pushTransition is applicable to most UIView - pushTransition适用于大多数UIView

1. Extension 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. Invocation 2.调用

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

3. Example 3.例子

Animation with a kCAMediaTimingFunctionEaseInEaseOut curve, a 0.4 second duration, and a kCATransitionFromTop direction . 使用kCAMediaTimingFunctionEaseInEaseOut曲线的动画,持续0.4秒,以及kCATransitionFromTop方向

CALayer动画


(†) Clipping is an important step for desired effect. (†)剪切是实现预期效果的重要步骤。

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

► Find this solution on GitHub and additional details on Swift Recipes . ►在GitHub上找到此解决方案以及有关Swift Recipes的其他详细信息。

Objective-C Objective-C的

The Swift UIView Extension can be solved in Objective-C with an Interface Extension . 可以使用Interface Extension在Objective-C中解决Swift UIView Interface Extension

1. The 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 Invocation 2. pushTransition调用

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

3. In Action 3.在行动中

UILabel动画


One-off: without Interface Extension: 一次性: 没有接口扩展:

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"];

Invocation: 调用:

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

QuartzCore provides a CATransition class for animated transition operations. QuartzCore为动画转换操作提供了CATransition类。 CATransition has the following definition: CATransition具有以下定义:

The CATransition class implements transition animations for a layer. CATransition类实现图层的过渡动画。 You can specify the transition effect from a set of predefined transitions or by providing a custom CIFilter instance. 您可以从一组预定义的转换中指定转换效果,也可以通过提供自定义CIFilter实例来指定转换效果。


In order to have your label's text transition animated by pushing upwards the old text, you'll have to create an instance of CATransition and set its type to kCATransitionPush and its subtype to kCATransitionFromTop : 为了通过向上推旧文本来CATransition标签的文本转换,您必须创建一个CATransition实例并将其type设置为kCATransitionPush并将其subtypekCATransitionFromTop

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

You will then be able to animate your label's text transition by adding the animation to your label's layer: 然后,您可以通过将动画添加到标签的图层来为标签的文本转换设置动画:

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

The following Swift 3 Playground code shows a possible implementation in order to animate a UILabel 's text transition using CATransition : 以下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