【问题标题】:Animate Text Change of UILabelUILabel 的动画文本更改
【发布时间】:2015-11-10 14:26:29
【问题描述】:

我想为 UILabel 中的文本更改设置动画。

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

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

但是,当第一个标签以动画方式越过帧的顶部时,如何切断它?

【问题讨论】:

  • 请发布您尝试自己解决此问题的任何尝试。
  • 通过在您的问题中提出 我可以通过 2 个标签来想办法,您可以将答案引向那个方向。然而,利用 Core Animation 有一个更短更优雅的方法。

标签: ios swift


【解决方案1】:

使用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 方向的动画


(†) 剪辑是获得所需效果的重要步骤。

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

► 在GitHub 上查找此解决方案,在Swift Recipes 上查找更多详细信息。

【讨论】:

  • 啊,这在 Swift 3 中不再有效。当我找到修复程序时会报告。
  • 在 Swift 3 中对我来说很好。只需更改一行:self.layer.add(animation, forKey: kCATransitionPush)
  • 有没有办法用弹簧推动画来做到这一点?
  • @SwiftArchitect ,用什么工具制作了这个 gif?请你告诉我好吗?找了好久。
  • @0xfba 我使用 screengif 效果很好。 github.com/dergachev/screengif
【解决方案2】:

Objective-C

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

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.行动中


一次性:接口扩展:

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

【讨论】:

    【解决方案3】:

    QuartzCore 为动画过渡操作提供了一个CATransition 类。 CATransition 有如下定义:

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


    为了通过向上推动旧文本来使标签的文本过渡动画化,您必须创建 CATransition 的实例并将其 type 设置为 kCATransitionPush 并将其 subtype 设置为 kCATransitionFromTop

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多