当一个文本比其他文本长时,UILabel 文本更改动画会闪烁
UILabel text change animation flickers when one text is longer than other
我正在使用理想的解决方案来为我的 UILabel 设置动画文本更改。类似于这个答案
问题是当文本长度不同时,动画不再流畅,文本在动画化之前会闪烁。
视频:https://drive.google.com/file/d/1I89NnzjQp7TbemO-dmcbKzYUr7pM7mGk/view?usp=sharing
我的代码如下所示:
@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()
}
我已经尝试过 layoutIfNeeded()、sizeToFit()、更改动画前的文本以及其他几个解决方法。似乎没有任何效果!
不确定您的示例中到底发生了什么,因为我无法生成此结果。但是动画在很多情况下是一种痛苦,很多东西可能会产生跳跃视图。
通过对动画有更多的控制,您可能会更好地找到问题或修复它。对于您的特定情况,使用快照制作动画可能已经足够了。查看以下内容:
@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)
}
}
如果您在上一个动画完成之前按下其中一个按钮,这仍然无法解决问题。要解决这个问题,可能还需要一些额外的努力。但目前这个解决方案可能就足够了。
我正在使用理想的解决方案来为我的 UILabel 设置动画文本更改。类似于这个答案
问题是当文本长度不同时,动画不再流畅,文本在动画化之前会闪烁。
视频:https://drive.google.com/file/d/1I89NnzjQp7TbemO-dmcbKzYUr7pM7mGk/view?usp=sharing
我的代码如下所示:
@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()
}
我已经尝试过 layoutIfNeeded()、sizeToFit()、更改动画前的文本以及其他几个解决方法。似乎没有任何效果!
不确定您的示例中到底发生了什么,因为我无法生成此结果。但是动画在很多情况下是一种痛苦,很多东西可能会产生跳跃视图。
通过对动画有更多的控制,您可能会更好地找到问题或修复它。对于您的特定情况,使用快照制作动画可能已经足够了。查看以下内容:
@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)
}
}
如果您在上一个动画完成之前按下其中一个按钮,这仍然无法解决问题。要解决这个问题,可能还需要一些额外的努力。但目前这个解决方案可能就足够了。