如何更新CABasicAnimation的toValue/fromValue更改时更平滑?
我申请了CAShapeLayer(让我们将其命名为pulseLayer
)2个动画,使用此代码:如何更新CABasicAnimation的toValue/fromValue更改时更平滑?
let scaledAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
scaledAnimation.duration = 0.75
scaledAnimation.repeatCount = Float.infinity
scaledAnimation.autoreverses = true
scaledAnimation.fromValue = 4
scaledAnimation.toValue = 4
scaledAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
let heartBeatAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
heartBeatAnimation.duration = 0.75
heartBeatAnimation.repeatCount = Float.infinity
heartBeatAnimation.autoreverses = true
heartBeatAnimation.fromValue = 1.0
heartBeatAnimation.toValue = 1.2
heartBeatAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
pulseLayer.add(heartBeatAnimation, forKey: "heartBeatAnimation")
在某些时候,而heartBeatAnimation
是我需要删除心脏跳动的动画,并用这个代码添加的缩放动画:
pulseLayer.add(self.scaledAnimation, forKey: "scaledAnimation")
pulseLayer.opacity = 0.55
pulseLayer.removeAnimation(forKey: "heartBeatAnimation")
,但我没有得到这两动画之间的平滑过渡,即使UIView.animate()
,所以我努力让自己只有一个动画heartBeatAnimation
并改变其toValue
fromValue
相同的值,以获得尽可能scaledAnimation
与此代码:
heartBeatAnimation.toValue = 4
heartBeatAnimation.fromValue = 4
什么都没有发生缩放稳定动画...!
所以任何想法如何更新这些值,使缩放的动画更平滑!
试试看看。完整的动画两者之间的切换是取决于CABasicAnimation的 duration, count, fromValue and toValue
性能与UIView.animate
关闭
@IBOutlet var vwAnimation: UIView!
let initialScale: CGFloat = 1.0
let animatingScale: CGFloat = 2.0
let finalScale: CGFloat = 3.0
override func viewDidLoad() {
super.viewDidLoad()
addAnimation()
}
func addAnimation(){
heartBeatAnimation()
self.perform(#selector(self.switchAnimation), with: nil, afterDelay: 3.0)
}
@objc func switchAnimation(){
UIView.animate(withDuration: 0.25, animations: {
self.vwAnimation.layer.removeAnimation(forKey: "heartBeatAnimation")
self.scaledAnimation()
self.vwAnimation.layoutIfNeeded()
}) { (isCompleted) in
}
}
func scaledAnimation() -> Void {
let scaledAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
scaledAnimation.duration = 0.5
scaledAnimation.repeatCount = 0.5
scaledAnimation.autoreverses = true
scaledAnimation.fromValue = initialScale
scaledAnimation.toValue = finalScale
scaledAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
vwAnimation.layer.add(scaledAnimation, forKey: "scaledAnimation")
self.perform(#selector(self.adjustScale), with: nil, afterDelay: 0.5)
}
@objc func adjustScale(){
self.vwAnimation.layer.removeAnimation(forKey: "scaledAnimation")
let scaleTransform = CGAffineTransform(scaleX: finalScale, y: finalScale)
vwAnimation.transform = scaleTransform
}
func heartBeatAnimation() -> Void {
let heartBeatAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
heartBeatAnimation.duration = 0.5
heartBeatAnimation.repeatCount = Float.infinity
heartBeatAnimation.autoreverses = true
heartBeatAnimation.fromValue = initialScale
heartBeatAnimation.toValue = animatingScale
heartBeatAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
vwAnimation.layer.add(heartBeatAnimation, forKey: "heartBeatAnimation")
}
这里是上面代码的结果,并让我知道如果想在这个结果的变化:
我要缩放并保持只是一个眨眼不进行缩放! –
我的意思是我想保持缩放。 –
Yaa,它在动画结束时缩放为'3x(scaleOfView = 3.0)',你可以在这里看到 – Krunal
不使用延迟等,并使用CATransaction和CASpringAnimations。
import UIKit
class ViewController: UIViewController {
var shapeLayer : CAShapeLayer!
var button : UIButton!
override func viewDidLoad() {
super.viewDidLoad()
//add a shapelayer
shapeLayer = CAShapeLayer()
shapeLayer.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width/4, height: self.view.bounds.width/4)
shapeLayer.position = self.view.center
shapeLayer.path = drawStarPath(frame: shapeLayer.bounds).cgPath
let color = UIColor(red: 0.989, green: 1.000, blue: 0.000, alpha: 1.000)
shapeLayer.fillColor = color.cgColor
self.view.layer.addSublayer(shapeLayer)
//button for action
button = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width - 20, height: 50))
button.center = self.view.center
button.center.y = self.view.bounds.height - 70
button.addTarget(self, action: #selector(ViewController.pressed(sender:)), for: .touchUpInside)
button.setTitle("Animate", for: .normal)
button.setTitleColor(.blue, for: .normal)
self.view.addSubview(button)
}
func pressed(sender:UIButton) {
if button.titleLabel?.text == "Reset Layer"{
reset()
return
}
//perform Animation
button.isEnabled = false
button.setTitle("Animating...", for: .normal)
let heartBeatAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
heartBeatAnimation.duration = 0.5
heartBeatAnimation.repeatCount = 2
heartBeatAnimation.autoreverses = true
heartBeatAnimation.fromValue = 1.0
heartBeatAnimation.toValue = 2.0
heartBeatAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
CATransaction.begin()
CATransaction.setCompletionBlock {
//call when finished
[weak self] in
if let vc = self{
vc.scaleUpToComplete()
}
}
shapeLayer.add(heartBeatAnimation, forKey: "beatAnimation")
CATransaction.commit()
}
func scaleUpToComplete(){
let scaledAnimation = CASpringAnimation(keyPath: "transform.scale.xy")
scaledAnimation.duration = 0.7
scaledAnimation.fromValue = 1.0
scaledAnimation.toValue = 2.0
scaledAnimation.damping = 8.0
scaledAnimation.initialVelocity = 9
scaledAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
CATransaction.begin()
CATransaction.setCompletionBlock {
//set transform
[weak self] in
if let vc = self{
let scaleTransform = CATransform3DScale(CATransform3DIdentity, 2.0, 2.0, 1)
vc.shapeLayer.transform = scaleTransform
vc.shapeLayer.removeAllAnimations()
//button title and enabled
vc.button.isEnabled = true
vc.button.setTitle("Reset Layer", for: .normal)
}
}
shapeLayer.add(scaledAnimation, forKey: "scaleUp")
CATransaction.commit()
}
func reset(){
let scaledAnimation = CASpringAnimation(keyPath: "transform.scale.xy")
scaledAnimation.duration = 0.7
scaledAnimation.fromValue = 2.0
scaledAnimation.toValue = 1.0
scaledAnimation.damping = 8.0
scaledAnimation.initialVelocity = 9
scaledAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
CATransaction.begin()
CATransaction.setCompletionBlock {
//set transform
[weak self] in
if let vc = self{
let scaleTransform = CATransform3DScale(CATransform3DIdentity, 1.0, 1.0, 1)
vc.shapeLayer.transform = scaleTransform
vc.shapeLayer.removeAllAnimations()
vc.button.setTitle("Animate", for: .normal)
}
}
shapeLayer.add(scaledAnimation, forKey: "scaleDown")
CATransaction.commit()
}
func drawStarPath(frame: CGRect = CGRect(x: 0, y: 0, width: 140, height: 140)) ->UIBezierPath{
//// Star Drawing
let starPath = UIBezierPath()
starPath.move(to: CGPoint(x: frame.minX + 0.50000 * frame.width, y: frame.minY + 0.21071 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.60202 * frame.width, y: frame.minY + 0.35958 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.77513 * frame.width, y: frame.minY + 0.41061 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.66508 * frame.width, y: frame.minY + 0.55364 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.67004 * frame.width, y: frame.minY + 0.73404 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.50000 * frame.width, y: frame.minY + 0.67357 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.32996 * frame.width, y: frame.minY + 0.73404 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.33492 * frame.width, y: frame.minY + 0.55364 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.22487 * frame.width, y: frame.minY + 0.41061 * frame.height))
starPath.addLine(to: CGPoint(x: frame.minX + 0.39798 * frame.width, y: frame.minY + 0.35958 * frame.height))
return starPath
}
}
我认为你需要设置heartBeatAnimation.toValue = 4,heartBeatAnimation.fromValue = 0,为平稳过渡 – Hitesh