Ios 动画打开时,如何更改为CABasicAnimation的value/fromValue
我正在尝试更改CABasicAnimation的toValue/fromValue值,其中动画为Ios 动画打开时,如何更改为CABasicAnimation的value/fromValue,ios,animation,swift3,cabasicanimation,Ios,Animation,Swift3,Cabasicanimation,我正在尝试更改CABasicAnimation的toValue/fromValue值,其中动画为heartBeatAnimation let heartBeatAnimation = CABasicAnimation(keyPath: "transform.scale.xy") heartBeatAnimation.duration = 0.75 heartBeatAnimation.repeatCount = Float.infinity heartBeatAnimation
heartBeatAnimation
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.15
当动画处于打开状态时,我将在动画期间通过以下方式获取transform.scale
的当前值:
let currentValue = someView.layer.presentation()?.value(forKeyPath: "transform.scale")
heartBeatAnimation.fromValue = currentValue
heartBeatAnimation.toValue = currentValue
在我更改了值之后,heartBeatAnimation
将不会更改其toValue/fromValue
,直到我删除动画,然后再次添加
有没有办法在动画打开时实时进行这些更改 通过将“模型层当前比例”更新为“表示层比例”,然后使用“beginTime”属性的更新读取动画,可以使其实时显示,从而使动画看起来从未停止过。这里有一个例子
import UIKit
class ViewController: UIViewController {
var scale : CGFloat = 1.2
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)
}
@objc func pressed(sender:UIButton) {
var isInterupted = false
if let presentation = shapeLayer.presentation(){
if let animScale = presentation.value(forKeyPath: "transform.scale.xy"){
if let value = animScale as? CGFloat{
//set current animation spot
shapeLayer.transform = CATransform3DScale(CATransform3DIdentity, value, value, 1)
shapeLayer.removeAllAnimations()
scale += 0.2
isInterupted = true
print("The current toValue is \(scale)")
}
}
}
button.setTitle("Animating...", for: .normal)
let heartBeatAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
heartBeatAnimation.duration = 0.5
let beginTimeNeeded = (1/scale) * CGFloat(heartBeatAnimation.duration)
heartBeatAnimation.repeatCount = .greatestFiniteMagnitude
heartBeatAnimation.autoreverses = true
heartBeatAnimation.fromValue = 1.0
heartBeatAnimation.toValue = scale
if isInterupted == true{
heartBeatAnimation.beginTime = CFTimeInterval(beginTimeNeeded)
}
heartBeatAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
shapeLayer.add(heartBeatAnimation, forKey: "beatAnimation")
}
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
}
}
我按下按钮为动画添加更多比例。
结果如下:
您可以通过将模型层当前比例更新为表示层比例,然后使用beginTime属性的更新读取动画,使动画看起来从未停止,从而使其实时显示。这里有一个例子
import UIKit
class ViewController: UIViewController {
var scale : CGFloat = 1.2
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)
}
@objc func pressed(sender:UIButton) {
var isInterupted = false
if let presentation = shapeLayer.presentation(){
if let animScale = presentation.value(forKeyPath: "transform.scale.xy"){
if let value = animScale as? CGFloat{
//set current animation spot
shapeLayer.transform = CATransform3DScale(CATransform3DIdentity, value, value, 1)
shapeLayer.removeAllAnimations()
scale += 0.2
isInterupted = true
print("The current toValue is \(scale)")
}
}
}
button.setTitle("Animating...", for: .normal)
let heartBeatAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
heartBeatAnimation.duration = 0.5
let beginTimeNeeded = (1/scale) * CGFloat(heartBeatAnimation.duration)
heartBeatAnimation.repeatCount = .greatestFiniteMagnitude
heartBeatAnimation.autoreverses = true
heartBeatAnimation.fromValue = 1.0
heartBeatAnimation.toValue = scale
if isInterupted == true{
heartBeatAnimation.beginTime = CFTimeInterval(beginTimeNeeded)
}
heartBeatAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
shapeLayer.add(heartBeatAnimation, forKey: "beatAnimation")
}
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/fromValue
,直到我删除动画,然后再次添加!是否在动画中断后直接添加动画?是的,对toValue/fromValue
的任何更新都将在重新添加动画后进行@agibson007抱歉,因为迟到,工作和解决困难的问题,顺便说一句,谢谢你的回答。你的意思是获得刻度将停止动画?在我更改值后,heartBeatAnimation
将不会更改其toValue/fromValue
,直到我删除动画,然后再次添加!是否在动画中断后直接添加动画?是的,对toValue/fromValue
的任何更新都将在重新添加动画后进行@抱歉,迟到了,工作和解决困难的问题,顺便说一句,谢谢你的回答。