使用自定义UIBezierPath对视图边框进行动画处理

时间:2018-08-20 11:58:33

标签: swift uiviewanimation uibezierpath cabasicanimation ios-animations

我正在尝试使聊天带有“气泡”的应用程序,并且需要为每个气泡状态之间的过渡设置动画。

__path__ = __import__('pkgutil').extend_path(__path__, __name__)

因此,我编写了一个自定义UIBeziePath初始化程序,然后按照所述为UIView添加了扩展名。

但是当我尝试更新单元的状态时,什么也没有发生,它只是立即绘制路径。我该怎么办?

我附上了一些图片,以了解发生了什么事

enter image description here enter image description here

我弄错了,并用extension UIView { func makeRoundedCorners(topLeftRad: Double, topRightRad: Double, bottomRightRad: Double, bottomLeftRad: Double) { let path = UIBezierPath(roundedRect: self.bounds, topLeftRadius: CGFloat(topLeftRad), topRightRadius: CGFloat(topRightRad), bottomRightRadius: CGFloat(bottomRightRad), bottomLeftRadius: CGFloat(bottomLeftRad)) let maskLayer = CAShapeLayer() maskLayer.path = path.cgPath let animation = CABasicAnimation(keyPath: "path") animation.toValue = path.cgPath animation.duration = 1 maskLayer.add(animation, forKey: "makeRoundedCorners") self.layer.mask = maskLayer } } extension UIBezierPath { convenience init(roundedRect rect: CGRect, topLeftRadius r1: CGFloat, topRightRadius r2: CGFloat, bottomRightRadius r3: CGFloat, bottomLeftRadius r4: CGFloat) { let left = CGFloat(Double.pi) let up = CGFloat(1.5*Double.pi) let down = CGFloat(Double.pi / 2) let right = CGFloat(0.0) self.init() addArc(withCenter: CGPoint(x: rect.minX + r1, y: rect.minY + r1), radius: r1, startAngle: left, endAngle: up, clockwise: true) addArc(withCenter: CGPoint(x: rect.maxX - r2, y: rect.minY + r2), radius: r2, startAngle: up, endAngle: right, clockwise: true) addArc(withCenter: CGPoint(x: rect.maxX - r3, y: rect.maxY - r3), radius: r3, startAngle: right, endAngle: down, clockwise: true) addArc(withCenter: CGPoint(x: rect.minX + r4, y: rect.maxY - r4), radius: r4, startAngle: down, endAngle: left, clockwise: true) close() } }

替换了初始路径

但是现在这件事正在发生

enter image description here

2 个答案:

答案 0 :(得分:1)

您需要指定动画对象的fromValue属性。
这样,Core Animation知道如何在fromto值之间进行插值。

let animation = CABasicAnimation(keyPath: #keyPath(CAShapeLayer.path))
animation.fromValue = UIBezierPath(…).path
animation.toValue = path.cgPath
animation.duration = 1

顺便说一句,如果您想使用UIBezierPath生成具有良好圆角(也就是松鼠)的矩形,则可能要检查我的extension of UIBezierPath

答案 1 :(得分:1)

动画立即发生的原因是将相同的路径分配给maskLayer并用作动画的toValue

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath // same path used here...

let animation = CABasicAnimation(keyPath: "path")
animation.toValue = path.cgPath // ... as here
animation.duration = 1

maskLayer.add(animation, forKey: "makeRoundedCorners")
self.layer.mask = maskLayer

由于该路径是动画的预期最终值,因此需要提供一个值作为动画源。

注意:路径动画为“未定义” 如果两个路径具有不同数量的控制点或路段。