Reputation: 403
I have a UIButton
with a CAShapeLayer
inside it. This is part of the subclass's code:
private func addBeneathFill(){
didAddedBeneathFill = true
let halfBeneathFill = UIBezierPath()
halfBeneathFill.move(to: CGPoint(x: 0, y: frame.height / 2))
halfBeneathFill.addCurve(to: CGPoint(x: frame.width, y: frame.height / 2), controlPoint1: CGPoint(x: frame.width / 10, y: frame.height / 2 + frame.height / 10), controlPoint2: CGPoint(x: frame.width, y: frame.height / 2 + frame.height / 10))
halfBeneathFill.addLine(to: CGPoint(x: frame.width, y: frame.height))
halfBeneathFill.addLine(to: CGPoint(x: 0, y: frame.height))
halfBeneathFill.addLine(to: CGPoint(x: 0, y: frame.height / 2))
let path = halfBeneathFill.cgPath
let shapeLayer = CAShapeLayer()
shapeLayer.path = path
let fillColor = halfBeneathFillColor.cgColor
shapeLayer.fillColor = fillColor
shapeLayer.opacity = 0.3
layer.insertSublayer(shapeLayer, at: 2)
}
It works great as long as the UIButton
does not change in size. When it changes in size, the CAShapeLayer
just stays in it's original position. Of course I can run the method again when the UIButton
's frame has been changed, but in an animation it looks awful.
How can I correctly animate the CAShapeLayer
's size to be always the current size of the UIButton
?
Upvotes: 1
Views: 62
Reputation: 716
You need to recalculate and animate your path on button frame change.
private func animateShapeLayer() {
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = getBezierPath(forFrame: oldFrame)
animation.toValue = getBezierPath(forFrame: newFrame)
animation.duration = 1.0
animation.fillMode = kCAFillModeForwards
animation.isRemovedOnCompletion = false
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
shapeLayer.add(animation, forKey: "path")
}
I've tested it, here you have a link to the playground gist and achieved result:
Upvotes: 1