gpt4 book ai didi

ios - 如何为 CATextLayer 的字符串设置动画?

转载 作者:行者123 更新时间:2023-11-28 10:39:00 27 4
gpt4 key购买 nike

我目前正在使用 AVMutableComposition 在视频中叠加一些文本,我想根据某个时间间隔重复更改字符串。我正在尝试使用核心动画来实现这一点;但是,字符串属性似乎不可设置动画。有没有其他方法可以达到目的?谢谢。

代码(不工作):

func getSubtitlesAnimation(withFrames frames: [String], duration: CFTimeInterval)->CAKeyframeAnimation {
let animation = CAKeyframeAnimation(keyPath:"string")
animation.calculationMode = kCAAnimationDiscrete
animation.duration = duration
animation.values = frames
animation.keyTimes = [0,0.5,1]
animation.repeatCount = Float(frames.count)
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeForwards
animation.beginTime = AVCoreAnimationBeginTimeAtZero
return animation
}

最佳答案

字符串不是 CATextLayer 上的动画路径。这是 list of keyPaths你可以在任何 CALayer 上使用。

关于将 Core Animation 与 AVFoundation 一起使用的其他一些重要事项。

  • 所有的动画都必须有 removedCompletion 的 false。
  • 您只能将一个关键路径动画应用于一个图层一次。这意味着如果你想添加淡入和淡出的不透明度,它需要组合成一个关键帧动画。在核心动画中,您可以使用 beginTime 并应用两个不同的不透明度动画,但根据我使用 AVFoundation 和核心动画的经验,这不起作用。因此,如果您想在 CALayer 的同一键路径上使用两种不同的(前不透明度)动画,您将必须计算出您希望发生什么的键时间和值。
  • 您的离散曲线仍然有效,但您必须计算出关键时间和值。
  • 因为字符串不能用作动画属性,所以下一个最好的办法是使用多个 CATextLayer 并将它们一个接一个地淡入淡出。这是一个例子。将 CACurrentMediaTime() 替换为 AVCoreAnimationBeginTimeAtZero 以便与 AVFoundation 一起使用。这只是一个示例,因此您可以想象您想要什么。

Example1Using-Discrete

 import UIKit

class ViewController: UIViewController {

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

//center the frame
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()) {
//animation spacing could be a negative value of half the animation to appear to fade between strings
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
//have to fade in and out with a single animation because AVFoundation
//won't allow you to animate the same propery on the same layer with
//two different animations
animation.values = [0,1,1,0,0]
animation.keyTimes = [0,0.001,0.99,0.999,1]
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeBoth
//Replace with AVCoreAnimationBeginTimeAtZero for AVFoundation
animation.beginTime = CACurrentMediaTime() + startTime
return animation
}
}

示例 2 - 使用长淡入淡出的 Gif 附件

import UIKit

class ViewController: UIViewController {

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

//center the frame
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()) {
//animation spacing could be a negative value of half the animation to appear to fade between strings
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
//have to fade in and out with a single animation because AVFoundation
//won't allow you to animate the same propery on the same layer with
//two different animations
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
//Replace with AVCoreAnimationBeginTimeAtZero for AVFoundation
animation.beginTime = CACurrentMediaTime() + startTime
return animation
}
}

结果:持续时间为 2 秒进出 2 秒。可以是即时的。 resultgif

关于ios - 如何为 CATextLayer 的字符串设置动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51722320/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com