我需要为 CATextLayer
制作动画的 bounds.size.height
, position
, 和 fontSize
.当我将它们添加到 CAAnimationGroup
时, 文字在动画中抖动,就像这样:
文本的跟踪值(字符之间的间距)的抖动似乎在动画时发生 fontSize
与 bounds.size.height
和/或 position
.我隔离了fontSize
,并且它自己表现良好。
如何防止 CATextLayer
中的文本抖动?如果我同时对边界和字体大小进行动画处理?
编辑
我已经不再制作动画 bounds
.现在,我只关心 fontSize
+ position
.这里有两个视频显示了差异。
fontSize
仅(平滑):https://youtu.be/FDPPGF_FzLI
fontSize
+ position
(紧张不安):https://youtu.be/3rFTsp7wBzk
这是它的代码。
let startFontSize: CGFloat = 16
let endFontSize: CGFloat = 30
let startPosition: CGPoint = CGPoint(x: 40, y: 100)
let endPosition: CGPoint = CGPoint(x: 20, y: 175)
// Initialize the layer
textLayer = CATextLayer()
textLayer.string = "Hello how are you?"
textLayer.font = UIFont.systemFont(ofSize: startFontSize, weight: UIFont.Weight.semibold)
textLayer.fontSize = startFontSize
textLayer.alignmentMode = kCAAlignmentLeft
textLayer.foregroundColor = UIColor.black.cgColor
textLayer.contentsScale = UIScreen.main.scale
textLayer.isWrapped = true
textLayer.backgroundColor = UIColor.lightGray.cgColor
textLayer.anchorPoint = CGPoint(x: 0, y: 0)
textLayer.position = startPosition
textLayer.bounds.size = CGSize(width: 450, height: 50)
view.layer.addSublayer(textLayer)
// Animate
let damping: CGFloat = 20
let mass: CGFloat = 1.2
var animations = [CASpringAnimation]()
let fontSizeAnim = CASpringAnimation(keyPath: "fontSize")
fontSizeAnim.fromValue = startFontSize
fontSizeAnim.toValue = endFontSize
fontSizeAnim.damping = damping
fontSizeAnim.mass = mass
fontSizeAnim.duration = fontSizeAnim.settlingDuration
animations.append(fontSizeAnim)
let positionAnim = CASpringAnimation(keyPath: "position.y")
positionAnim.fromValue = textLayer.position.y
positionAnim.toValue = endPosition.y
positionAnim.damping = damping
positionAnim.mass = mass
positionAnim.duration = positionAnim.settlingDuration
animations.append(positionAnim)
let animGroup = CAAnimationGroup()
animGroup.animations = animations
animGroup.duration = fontSizeAnim.settlingDuration
animGroup.isRemovedOnCompletion = true
animGroup.autoreverses = true
textLayer.add(animGroup, forKey: nil)
我的设备运行的是 iOS 11.0。
编辑 2
我逐帧分解了每个动画(仅 fontSize
和 fontSize
+ position
)。在每个视频中,我一次前进一帧。
在fontSize
仅视频 ( https://youtu.be/DZw2pMjDcl8 ),每一帧 都会增加 fontSize
,所以没有波涛汹涌。
在fontSize
+ position
视频 ( https://youtu.be/_idWte92F38 ), position
在每一帧更新,但不是fontSize
强>。只增加了fontSize
在 60% 的帧中,这意味着 fontSize
动画与 position
不同步,导致感知到的斩波。
所以也许正确的问题是:为什么 fontSize
当它是添加到图层的唯一动画时在每一帧中进行动画处理,但当作为 CAAnimationGroup
的一部分添加时则不进行动画处理结合 position
动画?
最佳答案
Apple DTS 认为此问题是一个错误。已提交报告。
与此同时,我将使用 CADisplayLink
将 CATextLayer.fontSize
的重绘与设备的刷新率同步,这将重绘图层在每一帧中适当的fontSize
。
编辑
在对 CADisplayLink
进行了大约一天的修改之后,绘制到正确的 fontSize
证明是困难的,尤其是在与自定义计时功能配对时。因此,我将完全放弃 CATextLayer
,并返回到 UILabel
。
在 WWDC '17's Advanced Animations with UIKit , Apple 建议使用“ View 变形”在两个标签状态之间制作动画——即两个 View 的平移、缩放和不透明度混合。 UIViewPropertyAnimator
为此提供了很大的灵 active ,例如混合多个计时功能和擦洗。 View 变形对于在 2 个 text
值之间转换也很有用,而无需淡出文本表示、更改 text
和淡入。
我确实希望 Apple 可以加强 CATextLayer
对非交互式动画的支持,因为我更喜欢使用一个 View 来为相同的文本表示设置动画。
关于ios - 断断续续的 CATextLayer 动画 : fontSize + position concurrently,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46700859/