为什么我的 CAShapeLayer 不能正确地使用 UIView (w/gif) 设置动画?
Why is my CAShapeLayer not animating correctly with the UIView (w/ gif)?
好的,事情是这样的。
灰色区域是一个UIView,用CAShapeLayer
遮蔽了它。我附加了两个 UIBezierPath
并使用 Even Odd Rule
删除了该灰色区域的一部分。这就是为什么它显示一条线,好像它在左侧显示一个半圆。
红色背景只是容器视图。
现在我的问题是,当我为我的 UIView
设置动画时,好像遮罩没有通过设置动画 UIView
正确更新。
这是 UIView
动画部分:
func didCompleteItem() {
self.bar.plainProgressBarLeftAnchor?.constant = self.bar.bounds.width * (self.completedItemCount*self.barMeterMultiplier) / self.bar.bounds.width - self.bar.meterCornerRadius
UIView.animate(withDuration: 1.0, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: {
self.bar.layoutIfNeeded()
}, completion: nil)
}
现在,这是其中的 layoutSubviews
部分,如果您需要查看 CAShapeLayer
是如何创建的。
override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = GradientColor(.leftToRight, frame: self.bounds, colors: GradientFlatRed())
layer.masksToBounds = true
layer.cornerRadius = meterCornerRadius
createMask()
}
var shapeLayer: CAShapeLayer = CAShapeLayer()
func createMask() {
let bPath = UIBezierPath(roundedRect: plainProgressBar.bounds, byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 0, height: 0))
let semiCircle = UIBezierPath(arcCenter: CGPoint(x: bounds.origin.x, y: plainProgressBar.bounds.origin.y+meterCornerRadius), radius: meterCornerRadius, startAngle: 3 * CGFloat.pi / 2, endAngle: CGFloat.pi / 2, clockwise: true)
shapeLayer.frame = layer.bounds
bPath.append(semiCircle)
shapeLayer.path = bPath.cgPath
shapeLayer.fillRule = kCAFillRuleEvenOdd
plainProgressBar.layer.mask = shapeLayer
}
绘制一个可拉伸的圆圈并更改描绘该圆圈的图像视图的宽度将为您提供您想要的效果,几乎不费吹灰之力,而且您遇到的瑕疵 none:
好的,事情是这样的。
灰色区域是一个UIView,用CAShapeLayer
遮蔽了它。我附加了两个 UIBezierPath
并使用 Even Odd Rule
删除了该灰色区域的一部分。这就是为什么它显示一条线,好像它在左侧显示一个半圆。
红色背景只是容器视图。
现在我的问题是,当我为我的 UIView
设置动画时,好像遮罩没有通过设置动画 UIView
正确更新。
这是 UIView
动画部分:
func didCompleteItem() {
self.bar.plainProgressBarLeftAnchor?.constant = self.bar.bounds.width * (self.completedItemCount*self.barMeterMultiplier) / self.bar.bounds.width - self.bar.meterCornerRadius
UIView.animate(withDuration: 1.0, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: {
self.bar.layoutIfNeeded()
}, completion: nil)
}
现在,这是其中的 layoutSubviews
部分,如果您需要查看 CAShapeLayer
是如何创建的。
override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = GradientColor(.leftToRight, frame: self.bounds, colors: GradientFlatRed())
layer.masksToBounds = true
layer.cornerRadius = meterCornerRadius
createMask()
}
var shapeLayer: CAShapeLayer = CAShapeLayer()
func createMask() {
let bPath = UIBezierPath(roundedRect: plainProgressBar.bounds, byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 0, height: 0))
let semiCircle = UIBezierPath(arcCenter: CGPoint(x: bounds.origin.x, y: plainProgressBar.bounds.origin.y+meterCornerRadius), radius: meterCornerRadius, startAngle: 3 * CGFloat.pi / 2, endAngle: CGFloat.pi / 2, clockwise: true)
shapeLayer.frame = layer.bounds
bPath.append(semiCircle)
shapeLayer.path = bPath.cgPath
shapeLayer.fillRule = kCAFillRuleEvenOdd
plainProgressBar.layer.mask = shapeLayer
}
绘制一个可拉伸的圆圈并更改描绘该圆圈的图像视图的宽度将为您提供您想要的效果,几乎不费吹灰之力,而且您遇到的瑕疵 none: