简体   繁体   中英

Animated CGAffineTransform(rotate) of a UIBezier path that is under func draw()

I want to make an animated of a path with CGAffineTransform(rotationAngle:) that is under a UIView`s draw. I couldn't find any way to do it...

This is my code:

     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)
         }         

And this is what I'm trying to do:

    func rotateButton() {

            UIView.animate(withDuration: 1, animations: {

                self.arrow.setAffineTransform(CGAffineTransform(rotationAngle:self.radians(self.arrowDegree + 10)))

                self.setNeedsDisplay()


            })

        }        

I don't know if I was specific.. tell me if more information is needed.

I would recommend that you separate the animation from the drawing. Overriding draw() is generally suited for custom drawing but ill-suited for any type of animation.

Based on the properties that's being assigned to arrow it looks like it's a CAShapeLayer . This is good because it means that there is already some separation between the two.

However , it's not a good idea to add subviews or sublayers inside of draw() . It should only be used for drawing. Otherwise these things are going to get re-added every time the view is redrawn. In this case it's less noticeable because the same layer is added over and over. But it should still be avoided.

You can still use draw() to render the centered dot. But it's not expected to be part of the animation.

As for the rotation animation; unless I greatly misremember the underlying mechanics, standalone layers (those that aren't backing a view (most likely you've created them)) don't care about the UIView animation context. Instead you would use a Core Animation level API to animate them. This could either be done by changing the property within a CATransaction , or by creating a CABasicAnimation from one angle to the other and adding it to the layer.

Note that adding an animation doesn't change the "model" value (the properties of the layer), and that once the animation finishes the layer would render as it did before the animation was added. If the layer is expected to animate to a value and stay there you would both add the animation and update the layer property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM