Search code examples
iosobjective-ccore-animationcore-graphicscalayer

A CALayer subLayer is being drawn with different frame origin. Bounds issue


I add a CAShapeLayer as subLayer to self.layer in a given view that way:

//balloonrect's value is this one
_balloonRect = CGRectMake(0, 55, 239, 118);

CAShapeLayer *balloonFrame = [CAShapeLayer layer];
balloonFrame.cornerRadius = 15.0f;
balloonFrame.frame = _balloonRect;
balloonFrame.fillColor = _balloonColor.CGColor;
balloonFrame.strokeColor = _balloonStrokeColor.CGColor;
balloonFrame.lineWidth = 5.0f;
balloonFrame.lineCap = kCALineCapRound;
balloonFrame.lineJoin = kCALineJoinRound;
balloonFrame.masksToBounds = YES;
UIBezierPath *fillPath = [UIBezierPath bezierPathWithRoundedRect: CGRectInset( _balloonRect, balloonFrame.lineWidth, balloonFrame.lineWidth) cornerRadius: 15.0f];
balloonFrame.path = fillPath.CGPath;

But, can't understand why, the shape is drawn under the height specified in balloonRect , it appears to be 110 px instead of 55 as it should. Strangely if I add the line

    balloonFrame.bounds = _balloonRect;

after setting the layer's frame everything seems to be fine, what is happening precisely? why do I have to set the bounds if they're for the layer himself?


Solution

    1. The height of balloonRect is not 55, it's 118. CGRectMake goes (x-top-left, y-top-left, width, height).

    2. Changing the bounds of something so as to have non-zero x-top-left and y-top-left shifts its drawing origin, so you are then shoving the drawing up and to the left (without actually changing the size of the layer).

    You might be helped by reading the sections in my book about frame and bounds, starting here: http://www.apeth.com/iOSBook/ch14.html#_frame