In short:
- Apple does NOT set the
frame
orbounds
for aCAShapeLayer
automatically (and Apple HAS NOT implemented an equivalent of[UIView sizeThatFits]
) - If you set the frame using the size of the bounding-box of the path ... everything goes wrong. No matter how you try to set it, it screws-up the path
So, what's the correct way to programmatically set the frame of a newly-created CAShapeLayer
with a newly-added CGPath
? Apple's docs are silent on the matter.
Things I've tried, that don't work:
- Create a
CAShapeLayer
- Create a
CGPath
, add it to the layer - Check the layer's
frame
- it's{{0,0},{0,0}}
- Set:
layer.frame = CGPathGetBoundingBox( layer.path )
Frame is now correct, but the path is now DOUBLE offset - changing the
frame
causes the path to effectively be shifted an extra(x,y)
pixelsSet:
layer.bounds = CGPathGetBoundingBox( layer.path )
- ...it all goes nuts. Nothing makes sense any more
- Try fixing it by doing
layer.position = CGPathGetBoundingBox( layer.path ).origin
- ...no dice; still nuts.
One thing I've tried that DID work, but causes problems elsewhere:
EDIT: this BREAKS as soon as you auto-rotate the screen. My guess: Apple's auto-rotate requires control of the "transform" property.
- Create a
CAShapeLayer
- Create a
CGPath
, add it to the layer - Check the layer's frame - it's
{{0,0},{0,0}}
- Set:
layer.frame = CGPathGetBoundingBox( layer.path )
- Set:
layer.transform = CGAffineTransformMakeTranslation( CGPathGetBoundingBox( layer.path ).origin.x * -1, // same for y-coord: set it to "-1 * the path's origin
This works, but ... lots of 3rd party code assumes that the initial transform for a CALayer
is Identity.
It shouldn't be this difficult! Surely there's something I'm doing wrong here?
(I've had one suggestion: "every time you add a path, manually run a custom function to shift all the points by -1 * (top-left-point.x, top-left-point.y)
". Again, that works - but it's ridiculously complex)