使用 UIView.Animate 的简单动画
Simple animation using UIView.Animate
我正在尝试创建我的自定义 activity 指标,这是我目前所拥有的:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 180, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor.green.cgColor
shapeLayer.lineWidth = 20
shapeLayer.lineCap = CAShapeLayerLineCap.round
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeEnd = 0
view.layer.addSublayer(shapeLayer)
UIView.animate(withDuration: 10, delay: 0, options: [], animations: {
let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.toValue = 1
basicAnimation.duration = 2
basicAnimation.fillMode = CAMediaTimingFillMode.forwards
basicAnimation.isRemovedOnCompletion = false
self.shapeLayer.add(basicAnimation, forKey: "key")
}) { (finished) in
if finished {
self.shapeLayer.removeFromSuperlayer()
}
}
}
所以,动画完成后,我会呈现一个新的控制器什么的。问题是立即调用完成。那么,我怎么能等
您可以添加延迟调度程序,延迟完全等于duration
:
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
// The job has to be done after animation
}
或者您可以使用 CATransaction.setCompletionBlock
,但它需要对 CA
本身有更深入的了解,您可能希望使用第一个选项。
UIView.animate()
和 CABasicAnimation
是两个不同的东西。立即调用完成,因为 UIView.animate()
方法不知道另一个方法发生了什么。它看不到 standard UIView 动画,因此触发完成块。
实现此目的的一种方法是使用 animationDidStop
委托方法。您需要将动画委托设置到视图、控制器,然后让它实现相关的回调。
添加这两行:
basicAnimation.setValue("strokeEnd", forKey: "animationID")
basicAnimation.delegate = self
然后确保视图控制器符合 CAAnimationDelegate
协议(通过在其声明中的 UIViewController
之后添加)并实现此委托方法:
override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
if let animationID: Any = anim.valueForKey("animationID") {
if animationID as String == "strokeEnd" {
// Your code here
}
}
}
归功于
我正在尝试创建我的自定义 activity 指标,这是我目前所拥有的:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let center = view.center
let circularPath = UIBezierPath(arcCenter: center, radius: 180, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor.green.cgColor
shapeLayer.lineWidth = 20
shapeLayer.lineCap = CAShapeLayerLineCap.round
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeEnd = 0
view.layer.addSublayer(shapeLayer)
UIView.animate(withDuration: 10, delay: 0, options: [], animations: {
let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.toValue = 1
basicAnimation.duration = 2
basicAnimation.fillMode = CAMediaTimingFillMode.forwards
basicAnimation.isRemovedOnCompletion = false
self.shapeLayer.add(basicAnimation, forKey: "key")
}) { (finished) in
if finished {
self.shapeLayer.removeFromSuperlayer()
}
}
}
所以,动画完成后,我会呈现一个新的控制器什么的。问题是立即调用完成。那么,我怎么能等
您可以添加延迟调度程序,延迟完全等于duration
:
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
// The job has to be done after animation
}
或者您可以使用 CATransaction.setCompletionBlock
,但它需要对 CA
本身有更深入的了解,您可能希望使用第一个选项。
UIView.animate()
和 CABasicAnimation
是两个不同的东西。立即调用完成,因为 UIView.animate()
方法不知道另一个方法发生了什么。它看不到 standard UIView 动画,因此触发完成块。
实现此目的的一种方法是使用 animationDidStop
委托方法。您需要将动画委托设置到视图、控制器,然后让它实现相关的回调。
添加这两行:
basicAnimation.setValue("strokeEnd", forKey: "animationID")
basicAnimation.delegate = self
然后确保视图控制器符合 CAAnimationDelegate
协议(通过在其声明中的 UIViewController
之后添加)并实现此委托方法:
override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
if let animationID: Any = anim.valueForKey("animationID") {
if animationID as String == "strokeEnd" {
// Your code here
}
}
}
归功于