在CATextLayer上,字符串不是可动画路径。以下是可以用于任何CALayer的关键路径列表。
使用AVFoundation时需要注意以下几点:
- 所有动画都必须具有false的removedCompletion。
- 您只能一次向图层应用一个关键路径动画。这意味着,如果您想添加一个淡入淡出的不透明度,它需要被合并成一个关键帧动画。在核心动画中,您可以使用beginTime并应用两个不同的不透明度动画,但在我使用AVFoundation和核心动画的经验中,这样做行不通。因此,如果您想在同一关键路径CALayer上使用两种不同(例如不透明度)动画,则必须找出所需发生的关键时间和值。
- 您的离散曲线仍将起作用,但您需要解决关键时间和值。
- 由于字符串不可用作可动画属性,下一个最好的方法是使用多个CATextLayers并逐个淡入它们。这是一个示例。将CACurrentMediaTime()替换为AVCoreAnimationBeginTimeAtZero以与AVFoundation一起使用。这只是一个示例,让您可以想象您想要的东西。
示例1:使用离散曲线
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let textFrame = CGRect(x: (self.view.bounds.width - 200)/2, y: (self.view.bounds.height - 100)/2, width: 200, height: 50)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
self.animateText(subtitles: ["Hello","Good Morning","Good Afternoon","Good Evening","Goodnight","Goodbye"], duration: 2, animationSpacing: 0, frame: textFrame, targetLayer: self.view.layer)
}
}
func animateText(subtitles:[String],duration:Double,animationSpacing:Double,frame:CGRect,targetLayer:CALayer){
var currentTime : Double = 0
for x in 0..<subtitles.count{
let string = subtitles[x]
let textLayer = CATextLayer()
textLayer.frame = frame
textLayer.string = string
textLayer.font = UIFont.systemFont(ofSize: 20)
textLayer.foregroundColor = UIColor.black.cgColor
textLayer.fontSize = 20.0
textLayer.alignmentMode = kCAAlignmentCenter
let anim = getSubtitlesAnimation(duration: duration, startTime: currentTime)
targetLayer.addSublayer(textLayer)
textLayer.add(anim, forKey: "opacityLayer\(x)")
currentTime += duration + animationSpacing
}
}
func getSubtitlesAnimation(duration: CFTimeInterval,startTime:Double)->CAKeyframeAnimation {
let animation = CAKeyframeAnimation(keyPath:"opacity")
animation.duration = duration
animation.calculationMode = kCAAnimationDiscrete
animation.values = [0,1,1,0,0]
animation.keyTimes = [0,0.001,0.99,0.999,1]
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeBoth
animation.beginTime = CACurrentMediaTime() + startTime
return animation
}
}
示例2-使用长时间淡入淡出的Gif动画
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let textFrame = CGRect(x: (self.view.bounds.width - 200)/2, y: (self.view.bounds.height - 100)/2, width: 200, height: 50)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
self.animateText(subtitles: ["Hello","Good Morning","Good Afternoon","Good Evening","Goodnight","Goodbye"], duration: 4, animationSpacing: -2, frame: textFrame, targetLayer: self.view.layer)
}
}
func animateText(subtitles:[String],duration:Double,animationSpacing:Double,frame:CGRect,targetLayer:CALayer){
var currentTime : Double = 0
for x in 0..<subtitles.count{
let string = subtitles[x]
let textLayer = CATextLayer()
textLayer.frame = frame
textLayer.string = string
textLayer.font = UIFont.systemFont(ofSize: 20)
textLayer.foregroundColor = UIColor.black.cgColor
textLayer.fontSize = 20.0
textLayer.alignmentMode = kCAAlignmentCenter
let anim = getSubtitlesAnimation(duration: duration, startTime: currentTime)
targetLayer.addSublayer(textLayer)
textLayer.add(anim, forKey: "opacityLayer\(x)")
currentTime += duration + animationSpacing
}
}
func getSubtitlesAnimation(duration: CFTimeInterval,startTime:Double)->CAKeyframeAnimation {
let animation = CAKeyframeAnimation(keyPath:"opacity")
animation.duration = duration
animation.values = [0,0.5,1,0.5,0]
animation.keyTimes = [0,0.25,0.5,0.75,1]
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeBoth
animation.beginTime = CACurrentMediaTime() + startTime
return animation
}
}
结果:
2秒时长的进场和出场。可以是立即的。
![resultgif](https://istack.dev59.com/l80vR.gif)