Animation 为在drawRect()中绘制的贝塞尔路径设置动画

Animation 为在drawRect()中绘制的贝塞尔路径设置动画,animation,swift,shapes,bezier,Animation,Swift,Shapes,Bezier,我在drawRect()中绘制了这个形状 调用prepareForEditing函数时,我想设置矩形路径的动画。我试过了 func prepareForEditing(editing:Bool){ UIView.animateWithDuration(0.5, animations: { self.rectanglePath = makeNewShape() } ) } 什么也没发

我在
drawRect()中绘制了这个形状

调用
prepareForEditing
函数时,我想设置矩形路径的动画。我试过了

  func prepareForEditing(editing:Bool){
        UIView.animateWithDuration(0.5,
            animations: {
              self.rectanglePath = makeNewShape()
            }
       )
  }

什么也没发生。你能告诉我我的代码有什么问题吗?

要制作CGPath动画,你不能使用UIView.animation方法。 我创建了自定义UIView子类,向您展示如何设置CGPATH形状的动画,请参考注释并根据您的要求进行修改:

class MyView: UIView {

let shapeLayer = CAShapeLayer()
let maskLayer = CAShapeLayer()
var rectanglePath = UIBezierPath()

override func didMoveToSuperview() {
    super.didMoveToSuperview()

    backgroundColor = UIColor.clear

    // initial shape of the view
    rectanglePath = UIBezierPath(rect: bounds)

    // Create initial shape of the view
    shapeLayer.path = rectanglePath.cgPath
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.fillColor = UIColor.clear.cgColor
    layer.addSublayer(shapeLayer)

    //mask layer
    maskLayer.path = shapeLayer.path
    maskLayer.position =  shapeLayer.position
    layer.mask = maskLayer
}

func prepareForEditing(editing:Bool){

    let animation = CABasicAnimation(keyPath: "path")
    animation.duration = 2

    // Your new shape here
    animation.toValue = UIBezierPath(ovalIn: bounds).cgPath
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

    // The next two line preserves the final shape of animation,
    // if you remove it the shape will return to the original shape after the animation finished
    animation.fillMode = kCAFillModeForwards
    animation.isRemovedOnCompletion = false

    shapeLayer.add(animation, forKey: nil)
    maskLayer.add(animation, forKey: nil)
  }
}

UIBezierPath使用类似动画的加载程序(Swift 5)在UIButton上绘制边框


注意:

谢谢!
fillWithBlend
模式是否适用于ShapeLayers?我尝试了这种方法,但混合完全不起作用。我相信如果您将drawRect函数添加到MyView类中(与您拥有的3行代码完全相同),一切都应该是您想要的。为什么您在
didMoveToSuperview()
中绘制形状,而不是
drawRect()
如果您查看apple UIView文档,则应避免覆盖此方法,除非您必须这样做。这是因为它会影响性能。
class MyView: UIView {

let shapeLayer = CAShapeLayer()
let maskLayer = CAShapeLayer()
var rectanglePath = UIBezierPath()

override func didMoveToSuperview() {
    super.didMoveToSuperview()

    backgroundColor = UIColor.clear

    // initial shape of the view
    rectanglePath = UIBezierPath(rect: bounds)

    // Create initial shape of the view
    shapeLayer.path = rectanglePath.cgPath
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.fillColor = UIColor.clear.cgColor
    layer.addSublayer(shapeLayer)

    //mask layer
    maskLayer.path = shapeLayer.path
    maskLayer.position =  shapeLayer.position
    layer.mask = maskLayer
}

func prepareForEditing(editing:Bool){

    let animation = CABasicAnimation(keyPath: "path")
    animation.duration = 2

    // Your new shape here
    animation.toValue = UIBezierPath(ovalIn: bounds).cgPath
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

    // The next two line preserves the final shape of animation,
    // if you remove it the shape will return to the original shape after the animation finished
    animation.fillMode = kCAFillModeForwards
    animation.isRemovedOnCompletion = false

    shapeLayer.add(animation, forKey: nil)
    maskLayer.add(animation, forKey: nil)
  }
}
func animation(){
    CATransaction.begin()

    let layer : CAShapeLayer = CAShapeLayer()
    layer.strokeColor = UIColor.purple.cgColor
    layer.lineWidth = 3.0
    layer.fillColor = UIColor.clear.cgColor

    let path : UIBezierPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: self.btn.frame.size.width + 2, height: self.btn.frame.size.height + 2), byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 5.0, height: 0.0))
    layer.path = path.cgPath

    let animation : CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd")
    animation.fromValue = 0.0
    animation.toValue = 1.0

    animation.duration = 7.0

    CATransaction.setCompletionBlock{ [weak self] in
        print("Animation completed")
    }

    layer.add(animation, forKey: "myStroke")
    CATransaction.commit()
    self.btn.layer.addSublayer(layer)
}