我正在尝试创建自定义活动指示器,这是我到目前为止所拥有的:
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动画,因此触发了完成块。
实现此目的的一种方法是使用委托方法。您需要将动画委托设置为视图,控制器,然后使其实现相关的回调。添加这两行:
basicAnimation.setValue("shake", forKey: "animationID")
basicAnimation.delegate = self
然后实现委托方法:
override func animationDidStop(anim: CAAnimation!, finished flag: Bool) { // Unwrap the optional value for the key "animationID" then // if it's equal to the same value as the relevant animation, // execute the relevant code if let animationID: AnyObject = anim.valueForKey("animationID") { if animationID as NSString == "strokeEnd" { // Your code } } }