在 func draw() 下的 UIBezier 路径的动画 CGAffineTransform(rotate)
Animated CGAffineTransform(rotate) of a UIBezier path that is under func draw()
我想使用 CGAffineTransform(rotationAngle:) 在 UIView 的绘图下制作路径动画。我找不到任何方法...
这是我的代码:
public override func draw(_ rect: CGRect) {
//Drawing a dot at the center
let dotRadius = max(bounds.width/15, bounds.height/15)
let dotWidth:CGFloat = 10
let dotCenter = CGPoint(x:bounds.width/2, y: bounds.height/2)
let dotStartAngle: CGFloat = 0
let dotEndAngle: CGFloat = CGFloat(2 * M_PI) // π
var path = UIBezierPath(arcCenter: dotCenter,
radius: dotRadius/2,
startAngle: dotStartAngle,
endAngle: dotEndAngle,
clockwise: true)
path.lineWidth = dotWidth
counterColor.setStroke()
counterColor.setFill()
path.stroke()
path.fill()
arrowLayer.frame = CGRect(x:bounds.width/2, y: bounds.height/2, width: bounds.width, height: bounds.height)
arrow.path = UIBezierPath(rect: CGRect(x: 0, y:0 - 1, width: -250, height: 1)).cgPath
arrow.backgroundColor = UIColor.red.cgColor
arrow.fillColor = UIColor.clear.cgColor
arrow.strokeColor = counterColor.cgColor
arrow.anchorPoint = CGPoint(x:0.5, y:0.5)
arrow.lineWidth = 3
arrow.setAffineTransform(CGAffineTransform(rotationAngle:self.radians(arrowDegree)))
arrowLayer.addSublayer(arrow)
self.layer.addSublayer(arrowLayer)
}
这就是我想要做的:
func rotateButton() {
UIView.animate(withDuration: 1, animations: {
self.arrow.setAffineTransform(CGAffineTransform(rotationAngle:self.radians(self.arrowDegree + 10)))
self.setNeedsDisplay()
})
}
我不知道我是否具体..如果需要更多信息请告诉我。
我建议您将动画与绘图分开。覆盖 draw()
通常适用于自定义 绘图 但不适用于任何类型的动画。
根据分配给 arrow
的属性,它看起来像是 CAShapeLayer
。这很好,因为这意味着两者之间已经存在一些分离。
但是,在draw()
中添加子视图或子层并不是一个好主意。它应该只用于绘图。否则,每次重绘视图时,这些东西都会重新添加。在这种情况下,它不太明显,因为一遍又一遍地添加了同一层。但还是应该避免。
您仍然可以使用 draw()
渲染居中点。但预计它不会成为动画的一部分。
关于旋转动画;除非我严重记错了底层机制,否则独立层(那些不支持视图的层(很可能是您创建的))不关心 UIView 动画上下文。相反,您可以使用核心动画级别 API 来为它们设置动画。这可以通过更改 CATransaction
中的 属性 或通过创建从一个角度到另一个角度的 CABasicAnimation
并将其添加到图层来完成。
注意添加动画不会改变"model"值(层的属性),并且一旦动画完成,图层将像添加动画之前一样渲染。如果图层需要动画到一个值并保持在那里,您将 both 添加动画并更新图层 属性。
我想使用 CGAffineTransform(rotationAngle:) 在 UIView 的绘图下制作路径动画。我找不到任何方法...
这是我的代码:
public override func draw(_ rect: CGRect) {
//Drawing a dot at the center
let dotRadius = max(bounds.width/15, bounds.height/15)
let dotWidth:CGFloat = 10
let dotCenter = CGPoint(x:bounds.width/2, y: bounds.height/2)
let dotStartAngle: CGFloat = 0
let dotEndAngle: CGFloat = CGFloat(2 * M_PI) // π
var path = UIBezierPath(arcCenter: dotCenter,
radius: dotRadius/2,
startAngle: dotStartAngle,
endAngle: dotEndAngle,
clockwise: true)
path.lineWidth = dotWidth
counterColor.setStroke()
counterColor.setFill()
path.stroke()
path.fill()
arrowLayer.frame = CGRect(x:bounds.width/2, y: bounds.height/2, width: bounds.width, height: bounds.height)
arrow.path = UIBezierPath(rect: CGRect(x: 0, y:0 - 1, width: -250, height: 1)).cgPath
arrow.backgroundColor = UIColor.red.cgColor
arrow.fillColor = UIColor.clear.cgColor
arrow.strokeColor = counterColor.cgColor
arrow.anchorPoint = CGPoint(x:0.5, y:0.5)
arrow.lineWidth = 3
arrow.setAffineTransform(CGAffineTransform(rotationAngle:self.radians(arrowDegree)))
arrowLayer.addSublayer(arrow)
self.layer.addSublayer(arrowLayer)
}
这就是我想要做的:
func rotateButton() {
UIView.animate(withDuration: 1, animations: {
self.arrow.setAffineTransform(CGAffineTransform(rotationAngle:self.radians(self.arrowDegree + 10)))
self.setNeedsDisplay()
})
}
我不知道我是否具体..如果需要更多信息请告诉我。
我建议您将动画与绘图分开。覆盖 draw()
通常适用于自定义 绘图 但不适用于任何类型的动画。
根据分配给 arrow
的属性,它看起来像是 CAShapeLayer
。这很好,因为这意味着两者之间已经存在一些分离。
但是,在draw()
中添加子视图或子层并不是一个好主意。它应该只用于绘图。否则,每次重绘视图时,这些东西都会重新添加。在这种情况下,它不太明显,因为一遍又一遍地添加了同一层。但还是应该避免。
您仍然可以使用 draw()
渲染居中点。但预计它不会成为动画的一部分。
关于旋转动画;除非我严重记错了底层机制,否则独立层(那些不支持视图的层(很可能是您创建的))不关心 UIView 动画上下文。相反,您可以使用核心动画级别 API 来为它们设置动画。这可以通过更改 CATransaction
中的 属性 或通过创建从一个角度到另一个角度的 CABasicAnimation
并将其添加到图层来完成。
注意添加动画不会改变"model"值(层的属性),并且一旦动画完成,图层将像添加动画之前一样渲染。如果图层需要动画到一个值并保持在那里,您将 both 添加动画并更新图层 属性。