AUK4SO
AUK4SO

Reputation: 411

Associate CGAffineTransformRotation to CGAffineTransformTranslation

I am trying to rotate a custom view (VIEWA) added on a parent view based on touch gesture using CGAffineTransformRotate. Everything is working fine. Now, I have another view(VIEWB) added on the parent view which should follow the path traced by a corner of the VIEWA while being rotated.

What i did was to calculate the new coordinates of the VIEWB from the VIEWA transformation matrix and translated the subview. i.e

VIEWA.transform = CGAffineTransformRotate(startTransform, -angleDifference+M_PI_2);
CGFloat cosa = VIEWA.transform.a;
CGFloat msinb = VIEWA.transform.b;
CGFloat sinc = VIEWA.transform.c;
CGFloat cosd = VIEWA.transform.d;

CGFloat newX = VIEWB.center.x * cosa + VIEWB.center.y * msinb;
CGFloat newY = VIEWB.center.x * sinc + VIEWB.center.y * cosd;

CGFloat xdiff = newX - VIEWB.center.x;
CGFloat ydiff = newY - VIEWB.center.y;

VIEWB.transform = CGAffineTransformTranslate(VIEWB.transform, xdiff, ydiff);

But i could not get what i wanted. Can somebody help me ?

Update:

This is what I'm trying to do :(red dot is A and black popup is B):

enter image description here

Upvotes: 2

Views: 381

Answers (1)

rob mayoff
rob mayoff

Reputation: 385600

I assume you rotate view A but the red circle stays at a fixed position in view A's coordinate system. Thus the center of the red circle, in view A's coordinate system, should be something like easy to compute, like this:

CGPoint redCircleCenterInViewA = CGPointMake(CGRectGetMidX(viewA.bounds), 12);

You can simply convert that point to the parent view's coordinate system, like this:

CGPoint redCircleCenterInParentView = [viewA convertPoint:redCircleCenterInViewA
    toView:viewA.superview];

Then you can set view B's center to that point, minus half of view B's height:

viewB.center = CGPointMake(redCircleCenterInParentView.x,
    redCircleCenterInParentView.y - viewB.frame.size.height / 2);

UPDATE

I see that you actually have layer A, not view A. That only requires a slight modification. The message you send to a layer to convert coordinates is slightly different than the message you send to a view.

CALayer *layerA = ...;
UIView *parentView = ...;
UIView *viewB = ...;

CGPoint redCircleCenterInLayerA = CGPointMake(CGRectGetMidX(layerA.bounds), 12);

CGPoint redCircleCenterInParentView = [layerA convertPoint:redCircleCenterInLayerA
    toLayer:parentView.layer];

viewB.center = CGPointMake(redCircleCenterInParentView.x,
    redCircleCenterInParentView.y - viewB.frame.size.height / 2);

Note that there are also convertPoint:fromLayer: and convertPoint:fromView: messages. Don't let Xcode autocomplete the wrong one or you will be scratching your head!

Upvotes: 4

Related Questions