Ios cabasicaniation中的键值编码混淆

Ios cabasicaniation中的键值编码混淆,ios,swift,animation,cabasicanimation,key-value-coding,Ios,Swift,Animation,Cabasicanimation,Key Value Coding,我目前正在尝试创建一个自定义的UIControl,它具有基于触摸的动画。我的问题是,在调用func setValue forKeyPath方法时,transform和opacity关键路径没有被分开,尽管正在设置动画的层完全不同 简而言之: 当触摸开始和触摸结束时,(a)不透明度在名为背景圈的层上发生变化,并且(b)变换在顶层上应用CATTransferM3dRotate CALayer有一个扩展,它(a)通过addAnimation添加动画,以及(b)通过setValue简化代码来设置关键路径

我目前正在尝试创建一个自定义的UIControl,它具有基于触摸的动画。我的问题是,在调用
func setValue forKeyPath
方法时,
transform
opacity
关键路径没有被分开,尽管正在设置动画的层完全不同

简而言之:

  • 触摸开始
    触摸结束
    时,(a)
    不透明度
    在名为
    背景圈
    的层上发生变化,并且(b)
    变换
    顶层
    上应用
    CATTransferM3dRotate
  • CALayer
    有一个扩展,它(a)通过
    addAnimation
    添加动画,以及(b)通过
    setValue
    简化代码来设置关键路径的值
  • 问题在于,不透明度不会动画恢复为零,而是逐渐增加,直到其完全不透明。但是,当我将keyPath更改为除
    transform
    以外的任何内容时,它会再次工作,但不会为顶层设置动画。我不确定这里到底出了什么问题,但我怀疑这与关键路径有关

    以下是方法和扩展:

  • backgroundCircle
    相关功能:

    func animateCircleToTransparent(completion:()->()) {
    
    let drawAnimation = CABasicAnimation(keyPath: "opacity")
    drawAnimation.duration = 0.2
    drawAnimation.repeatCount = 1
    drawAnimation.fromValue = backgroundCircleOpacity
    drawAnimation.toValue = 0
    drawAnimation.fillMode = kCAFillModeBackwards
    drawAnimation.autoreverses = false
    drawAnimation.timingFunction = CAMediaTimingFunction(controlPoints: 0.34, 0.01, 0.69, 1.37)
    self.backgroundCircle.ocb_applyAnimation(drawAnimation)
    
    }
    
    func animateCircleToOpaque(completion:()->()) {
    
    let drawAnimation = CABasicAnimation(keyPath: "opacity")
    drawAnimation.duration = 0.2
    drawAnimation.repeatCount = 1
    drawAnimation.fromValue = 0
    drawAnimation.toValue = backgroundCircleOpacity
    drawAnimation.fillMode = kCAFillModeBackwards
    drawAnimation.autoreverses = false
    drawAnimation.timingFunction = CAMediaTimingFunction(controlPoints: 0.34, 0.01, 0.69, 1.37)
    self.backgroundCircle.ocb_applyAnimation(drawAnimation)
    }
    
    func animateTopLineOn() {
    
    let topTransform = CABasicAnimation(keyPath: "transform")
    topTransform.timingFunction = CAMediaTimingFunction(controlPoints: 0.5, -0.8, 0.5, 1.85)
    topTransform.duration = 0.4
    topTransform.fillMode = kCAFillModeBackwards
    
    let translation = CATransform3DMakeTranslation(-4, 0, 0)
    topTransform.toValue = NSValue(CATransform3D: CATransform3DRotate(translation, -0.7853975, 0, 0, 1))
    topTransform.beginTime = CACurrentMediaTime() + 0.25
    
    self.topLayer.ocb_applyAnimation(topTransform)
    }
    
    
    func animateTopLineOff() {
    
    
    let topTransform = CABasicAnimation(keyPath: "transform")
    topTransform.timingFunction = CAMediaTimingFunction(controlPoints: 0.5, -0.8, 0.5, 1.85)
    topTransform.duration = 0.4
    topTransform.fillMode = kCAFillModeBackwards
    
    let translation = CATransform3DMakeTranslation(4, 0, 0)
    topTransform.toValue = NSValue(CATransform3D: CATransform3DRotate(translation, 0.7853975, 0, 0, 1))
    topTransform.beginTime = CACurrentMediaTime() + 0.25
    
    self.topLayer.ocb_applyAnimation(topTransform)
    }
    
  • 顶层
    相关功能:

    func animateCircleToTransparent(completion:()->()) {
    
    let drawAnimation = CABasicAnimation(keyPath: "opacity")
    drawAnimation.duration = 0.2
    drawAnimation.repeatCount = 1
    drawAnimation.fromValue = backgroundCircleOpacity
    drawAnimation.toValue = 0
    drawAnimation.fillMode = kCAFillModeBackwards
    drawAnimation.autoreverses = false
    drawAnimation.timingFunction = CAMediaTimingFunction(controlPoints: 0.34, 0.01, 0.69, 1.37)
    self.backgroundCircle.ocb_applyAnimation(drawAnimation)
    
    }
    
    func animateCircleToOpaque(completion:()->()) {
    
    let drawAnimation = CABasicAnimation(keyPath: "opacity")
    drawAnimation.duration = 0.2
    drawAnimation.repeatCount = 1
    drawAnimation.fromValue = 0
    drawAnimation.toValue = backgroundCircleOpacity
    drawAnimation.fillMode = kCAFillModeBackwards
    drawAnimation.autoreverses = false
    drawAnimation.timingFunction = CAMediaTimingFunction(controlPoints: 0.34, 0.01, 0.69, 1.37)
    self.backgroundCircle.ocb_applyAnimation(drawAnimation)
    }
    
    func animateTopLineOn() {
    
    let topTransform = CABasicAnimation(keyPath: "transform")
    topTransform.timingFunction = CAMediaTimingFunction(controlPoints: 0.5, -0.8, 0.5, 1.85)
    topTransform.duration = 0.4
    topTransform.fillMode = kCAFillModeBackwards
    
    let translation = CATransform3DMakeTranslation(-4, 0, 0)
    topTransform.toValue = NSValue(CATransform3D: CATransform3DRotate(translation, -0.7853975, 0, 0, 1))
    topTransform.beginTime = CACurrentMediaTime() + 0.25
    
    self.topLayer.ocb_applyAnimation(topTransform)
    }
    
    
    func animateTopLineOff() {
    
    
    let topTransform = CABasicAnimation(keyPath: "transform")
    topTransform.timingFunction = CAMediaTimingFunction(controlPoints: 0.5, -0.8, 0.5, 1.85)
    topTransform.duration = 0.4
    topTransform.fillMode = kCAFillModeBackwards
    
    let translation = CATransform3DMakeTranslation(4, 0, 0)
    topTransform.toValue = NSValue(CATransform3D: CATransform3DRotate(translation, 0.7853975, 0, 0, 1))
    topTransform.beginTime = CACurrentMediaTime() + 0.25
    
    self.topLayer.ocb_applyAnimation(topTransform)
    }
    
  • “CALayer”扩展名:

    extension CALayer {
    func ocb_applyAnimation(animation: CABasicAnimation) {
    let copy = animation.copy() as! CABasicAnimation
    
    if copy.fromValue == nil {
        copy.fromValue = self.presentationLayer()!.valueForKeyPath(copy.keyPath!)
    }
    
    self.addAnimation(copy, forKey: copy.keyPath!)
    self.setValue(copy.toValue, forKeyPath:copy.keyPath!)
    }
    }