Search code examples
iosrotationlinear-algebracgaffinetransformaffinetransform

Positioning a view after transform rotation


I'm creating a custom popover background, so I subclassed the UIPopoverBackground abstract class. While creating the layout function I came across a problem with placing and rotating the arrow for the background.

The first picture shows the arrow at the desired position. In the following code I calculated the origin I wanted but the rotation seemed to have translated the new position of the image off to the side about 11 points. As you can see, I created a hack solution where I shifted the arrow over 11 points. But that still doesn't cover up the fact that I have a gapping hole in my math skills. If someone would be so kind as to explain to me what's going on here I'd be eternally grateful. What also would be nice is a solution that would not involve magic numbers, so that I could apply this solution to the cases with the up, down and right arrow

screen shot

#define ARROW_BASE_WIDTH 42.0
#define ARROW_HEIGHT 22.0

    case UIPopoverArrowDirectionRight:
    {
        width -= ARROW_HEIGHT;
        float arrowCenterY = self.frame.size.height/2 - ARROW_HEIGHT/2 + self.arrowOffset;
        _arrowView.frame = CGRectMake(width,
                                      arrowCenterY,
                                      ARROW_BASE_WIDTH,
                                      ARROW_HEIGHT);
        rotation = CGAffineTransformMakeRotation(M_PI_2);
        //rotation = CGAffineTransformTranslate(rotation, 0, 11);
         _borderImageView.frame = CGRectMake(left, top, width, height);
        [_arrowView setTransform:rotation];
    }
    break;

Solution

  • Well, if the rotation is applied about the center of the arrow view (as it is), that leaves a gap of (ARROW_BASE_WIDTH - ARROW_HEIGHT) / 2 to the post-rotation left of the arrow, which is what you have to compensate for, it seems. By offsetting the center of the arrow view by this much, it should come back into alignment.