Search code examples
ioscore-graphicsscalecgaffinetransform

iOS scaling with CGAffineTransformMakeScale on drawRect content


    float scaleFactor = 0.5;
    self.bubble.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);
    [self.bubble setNeedsDisplay];

    [UIView animateWithDuration:2.0 animations:^{
        self.frame = _rectToMoveTo;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2.0f animations:^{
            self.bubble.transform = CGAffineTransformMakeScale(1.0, 1.0);
        }];
    }];

The above code performs the animation mostly correct. As you can see, the self.bubbles are scaled down to ½ then animated back to normal. The problem is that self.bubble has a drawRect method for drawing a circle. The problem is that this circle gets scaled down to ¼ from the start! When the second animation runs, the subviews of self.bubble get scaled to normal, but the circle scales up to only ½. I've tried using setNeedsDisplay to redraw the circle but it will only work after the animations have completed so it's no good. how do you fix this?

Edit: here is _bubble drawRect method.

CGContextRef c = UIGraphicsGetCurrentContext();

    if (!_colour) _colour = [UIColor darkGrayColor];
    [_colour setFill];
    [[UIColor clearColor] setStroke];

    CGContextAddEllipseInRect(c, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height));

    CGContextFillPath(c);

    [self addSubview:_title];
    [self addSubview:_icon];

Solution

  • self.frame is in the superview's coordinate system, and is thus affected by your transform, which you don't want.

    Inside drawRect:, you should only use self.bounds, not self.frame.

    Also, you should not add subviews in drawRect:.