如果视图变得可动画,则有效地调整 CAShapeLayer 的大小
Efficient resize the CAShapeLayer if the view grows animatable
我有一个 UIButton
,里面有一个 CAShapeLayer
。这是子类代码的一部分:
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)
}
只要 UIButton
大小不变,它就很好用。当它改变大小时,CAShapeLayer
只是停留在它原来的位置。当然,当 UIButton
的帧已更改时,我可以再次 运行 该方法,但在动画中它看起来很糟糕。
如何正确地设置 CAShapeLayer
的大小始终为 UIButton
的当前大小?
您需要在按钮框架更改时重新计算路径并设置动画。
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")
}
我已经测试过了,这里你有一个 link 到 playground gist 并取得了结果:
我有一个 UIButton
,里面有一个 CAShapeLayer
。这是子类代码的一部分:
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)
}
只要 UIButton
大小不变,它就很好用。当它改变大小时,CAShapeLayer
只是停留在它原来的位置。当然,当 UIButton
的帧已更改时,我可以再次 运行 该方法,但在动画中它看起来很糟糕。
如何正确地设置 CAShapeLayer
的大小始终为 UIButton
的当前大小?
您需要在按钮框架更改时重新计算路径并设置动画。
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")
}
我已经测试过了,这里你有一个 link 到 playground gist 并取得了结果: