Search code examples
iosrotationuiimageviewuikitcore-animation

Rotating an image view which should be inside an arc with fixed point for bottom


I am creating a speed gauge. The bottom of my image has to be in a center point of my arc and I need to rotate the image with a fixed center point. I don't know how to to do it.

    private func drawHand(center: CGPoint) {
        let handImage = UIImage(named: "hand")
        handImageView = UIImageView(image: handImage)

        handImageView.translatesAutoresizingMaskIntoConstraints = false
        handImageView.bounds = CGRect(x: center.x, y: center.y, width: 100, height: bounds.height / 3)
        handImageView.layer.anchorPoint = CGPoint(x: 0, y: 0.5)

        handImageView.center = CGPoint(x: bounds.midX, y: bounds.midY)
        addSubview(handImageView)
    }

Here is my code where I am trying to center image inside the arc but my image is in the left corner instead.

To rotation I was trying to use

            handImageView.transform = CGAffineTransform(rotationAngle: deg2rad(handRotation))

but nothing working properly. Please help me with settting my image in the center of arc and then rotating its.


Solution

  • With this line:

    handImageView.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
    

    you've set the anchor point to the Left Edge and Vertical Center

    Change it to this:

    // set the anchorPoint to Horizontal Center / Bottom Edge
    handImageView.layer.anchorPoint = CGPoint(x: 0.5, y: 1.0)
    

    and see if you get the rotation you want.

    Here's a complete example... the arrow starts at Zero-degrees (pointing up) -- each tap will increment the rotation by 10-degrees:

    extension Double {
        var degreesToRadians: Self { self * .pi / 180 }
        var radiansToDegrees: Self { self * 180 / .pi }
    }
    
    class ViewController: UIViewController {
    
        var handImageView: UIImageView!
        
        var handRotation: Double = 0
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let handImage = UIImage(systemName: "arrow.up")
            handImageView = UIImageView(image: handImage)
            
            // so we can see the image view frame
            handImageView.backgroundColor = .systemYellow
            
            view.addSubview(handImageView)
            
            // set imageView frame to 80 x 160
            handImageView.frame = CGRect(origin: .zero, size: CGSize(width: 80, height: 160))
            
            // set the anchorPoint to Horizontal Center / Bottom Edge
            handImageView.layer.anchorPoint = CGPoint(x: 0.5, y: 1.0)
            
            // set image view's Anchor Point to the center of the view
            handImageView.center = view.center
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            // increment rotation by 10-degrees with each touch
            //  Zero-degrees is pointing UP (12 o'clock)
            handRotation += 10
            handImageView.transform = CGAffineTransform(rotationAngle: CGFloat(handRotation.degreesToRadians))
            print("rotation:", handRotation)
        }
    
    }