20

how to rotate CALayer at one selected point.

Brian Webster
  • 30,033
  • 48
  • 152
  • 225
kiran kumar
  • 1,349
  • 4
  • 21
  • 40

3 Answers3

37
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DTranslate(transform, rotationPoint.x-center.x, rotationPoint.y-center.y, 0.0);
transform = CATransform3DRotate(transform, rotationAngle, 0.0, 0.0, -1.0);
transform = CATransform3DTranslate(transform, center.x-rotationPoint.x, center.y-rotationPoint.y, 0.0);

Where center is the center of your layer, rotationAngle is in radians (positive is counterclockwise), and rotationPoint is the point about which you wish to rotate. center and rotationPoint are in the coordinate space of the containing view.

warrenm
  • 31,094
  • 6
  • 92
  • 116
7

enter image description here

  1. Define your sublayer that you want to rotate;
  2. Set its bounds, position in superlayer and anchorPoint. anchorPoint has relative coordinates and points to an anchorPoint. Your sublayer will rotate around this anchorPoint;
  3. Add transformation.

For example, to rotate a sublayer on its superview top center point around sublayer's bottom center, use this code:

    // 1
    let rect = CGRect(x: 0,
                      y: 0,
                      width: 20,
                      height: 20)
    let path = UIBezierPath(rect: rect)
    let sublayer = CAShapeLayer()
    sublayer.fillColor = UIColor.green.cgColor
    sublayer.path = path.cgPath
    superlayer.addSublayer(sublayer)

    // 2
    sublayer.bounds = rect
    sublayer.position = CGPoint(x: superlayer.bounds.size.width/2, y: 0)
    sublayer.anchorPoint = CGPoint(x: 0.5, y: 1)

    // 3
    let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
    rotationAnimation.toValue = 2*CGFloat.pi
    rotationAnimation.duration = 3
    rotationAnimation.fillMode = kCAFillModeForwards
    rotationAnimation.isRemovedOnCompletion = false
    sublayer.add(rotationAnimation, forKey: nil)
Valentin Shamardin
  • 3,569
  • 4
  • 34
  • 51
  • 1
    not sure why (maybe because of coordinate system mislead), but suggested code works only if I change `anchorPoint` to `CGPoint(x: 0.5, y: 0)` thanks for the detailed answer, much useful – rkyr Aug 22 '18 at 14:36
  • Adding an Animation with `forKey` as `nil` is going to increase memory usage if this is used more than once – fdcpp Apr 07 '20 at 14:43
0

Check out the CA documentation here.

You want to set the transform to a CATransform3DRotate, for example:

CATransform3D current = myLayer.transform;
myLayer.transform = CATransform3DRotate(current, DEGREES_TO_RADIANS(20), 0, 1.0, 0);
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Ben
  • 2,982
  • 1
  • 16
  • 12
  • 1
    This will only suffice for rotating the layer about its current center, not an arbitrary point. – warrenm Oct 14 '10 at 02:47