简体   繁体   English

当一个文本比另一个文本长时 UILabel 文本更改动画闪烁

[英]UILabel text change animation flickers when one text is longer than other

I am using the ideal solution to animate text changes to my UILabel.我正在使用理想的解决方案来为 UILabel 的文本更改设置动画。 Similar to this answer https://stackoverflow.com/a/33705634/8704900类似于这个答案https://stackoverflow.com/a/33705634/8704900
The problem is when the texts are not of same length, the animation is no more smooth and the text flickers before animating up.问题是当文本长度不同时,动画不再流畅并且文本在动画之前闪烁。
Video: https://drive.google.com/file/d/1I89NnzjQp7TbemO-dmcbKzYUr7pM7mGk/view?usp=sharing视频: https : //drive.google.com/file/d/1I89NnzjQp7TbemO-dmcbKzYUr7pM7mGk/view?usp=sharing

My code looks like this:我的代码如下所示:

@IBOutlet weak var label: UILabel!

var titleLabelAnimation: CATransition = {
        let animation = CATransition()
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
        animation.type = .push
        animation.subtype = .fromTop
        animation.duration = 0.5
        return animation
    }()

    @IBAction func didTap() {
        self.label.layer.add(self.titleLabelAnimation, forKey: nil)
        self.label.text = "Can you see a flicker?"
        self.label.sizeToFit()
    }
    
    @IBAction func didTapRev() {
        self.label.layer.add(self.titleLabelAnimation, forKey: nil)
        self.label.text = "Hello this is animation !!!"
        self.label.sizeToFit()
    }

I have tried layoutIfNeeded(), sizeToFit(), changing the text before animation and couple of other workarounds.我尝试过 layoutIfNeeded()、sizeToFit()、在动画之前更改文本以及其他一些解决方法。 Nothing seem to be working!似乎没有任何工作!

Not sure exactly what is going on in your example as I could not produce this result.不确定您的示例中究竟发生了什么,因为我无法产生此结果。 But animations are in many cases a pain and a lot of things may produce jumping views.但是动画在很多情况下是一种痛苦,很多事情可能会产生跳跃视图。

By having a bit more control over animation you might have better luck finding out the issue or fixing it.通过对动画有更多的控制,您可能会更幸运地发现问题或修复它。 For your specific case it might already be enough to do your animation using snapshots.对于您的特定情况,使用快照制作动画可能已经足够了。 Check out the following:查看以下内容:

@IBOutlet weak var label: UILabel!

private func animateAsCustom(applyChanges: @escaping (() -> Void)) {
    guard let viewToMove = label else { return }
    guard let panel = viewToMove.superview else { return }
    guard let snapshotView = viewToMove.snapshotView(afterScreenUpdates: true) else { return }
    
    applyChanges()
    
    UIView.performWithoutAnimation {
        panel.addSubview(snapshotView)
        snapshotView.center = viewToMove.center
        viewToMove.transform = CGAffineTransform(translationX: 0.0, y: 50.0) // TODO: compute values for translation
        viewToMove.alpha = 0.0
    }
    UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseIn) {
        viewToMove.transform = .identity
        snapshotView.transform = CGAffineTransform(translationX: 0.0, y: -50.0)
        snapshotView.alpha = 0.0
        viewToMove.alpha = 1.0
    } completion: { _ in
        snapshotView.removeFromSuperview()
    }
}

@IBAction func didTap() {
    animateAsCustom {
        self.label.numberOfLines = 1
        self.label.text = "Can you see a flicker?"
        self.label.textColor = .red
        self.label.font = UIFont.systemFont(ofSize: 20)
    }
}

@IBAction func didTapRev() {
    animateAsCustom {
        self.label.numberOfLines = 0
        self.label.text = "Hello this\nis animation !!!"
        self.label.textColor = .black
        self.label.font = UIFont.systemFont(ofSize: 30)
    }
}

This will still not fix the issue if you press one of the buttons before previous animation did finish.如果您在上一个动画完成之前按下其中一个按钮,这仍然无法解决问题。 To fix that one as well some extra effort may be needed.为了解决这个问题,可能需要一些额外的努力。 But for now this solution could be enough.但是现在这个解决方案可能就足够了。

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

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