calayer - Configuración del marco correcto de un CAShapeLayer recién creado
cgpath (1)
En breve:
- Apple NO establece el
frame
o losbounds
para unCAShapeLayer
automáticamente (y Apple NO HA implementado un equivalente de[UIView sizeThatFits]
) - Si establece el marco utilizando el tamaño del cuadro delimitador de la ruta ... todo irá mal. No importa cómo intentes configurarlo, arruina el camino.
Entonces, ¿cuál es la manera correcta de establecer mediante programación el marco de un CAShapeLayer
recién creado con un CAShapeLayer
recién agregado? Los documentos de Apple guardan silencio al respecto.
Cosas que he probado, que no funcionan:
- Crear un
CAShapeLayer
- Crea un
CGPath
,CGPath
a la capa. - Comprueba el
frame
la capa - es{{0,0},{0,0}}
- Establecer:
layer.frame = CGPathGetBoundingBox( layer.path )
El cuadro ahora es correcto, pero la ruta ahora está DOBLE en desplazamiento: cambiar el
frame
hace que la ruta se desplace de manera efectiva en píxeles adicionales(x,y)
Establecer:
layer.bounds = CGPathGetBoundingBox( layer.path )
- ... todo se vuelve loco. Ya nada tiene sentido
- Intenta arreglarlo haciendo
layer.position = CGPathGetBoundingBox( layer.path ).origin
- ...no dados; todavía loco
Una cosa he intentado que DID funcione, pero causa problemas en otros lugares:
EDITAR: esto BREAKS tan pronto como gire automáticamente la pantalla. Mi conjetura: la rotación automática de Apple requiere el control de la propiedad "transformar".
- Crear un
CAShapeLayer
- Crea un
CGPath
,CGPath
a la capa. - Comprueba el marco de la capa - es
{{0,0},{0,0}}
- Establecer:
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
Esto funciona, pero ... muchos de los códigos de terceros asumen que la transformación inicial para un CALayer
es Identidad.
¡No debería ser tan difícil! Seguramente hay algo que estoy haciendo mal aquí?
(He tenido una sugerencia: "cada vez que agregue una ruta, ejecute manualmente una función personalizada para desplazar todos los puntos en -1 * (top-left-point.x, top-left-point.y)
". De nuevo , eso funciona - pero es ridículamente complejo)
La configuración de layer.bounds a los límites de la ruta es lo correcto: desea hacer que el espacio de coordenadas locales de la capa coincida con la ruta. Pero también es necesario que establezca la propiedad de posición de la capa para moverla al lugar correcto en su capa superior.
(La configuración de .frame se traduce en el marco que calcula los valores correctos de .bounds y .position para usted, pero siempre deja los límites.origen sin tocar, que no es lo que desea cuando los límites de su ruta tienen un origen distinto de cero).
Así que algo como esto debería funcionar, asumiendo que no ha cambiado el punto de anclaje de su valor habitual (.5, .5) y desea colocar la capa al ras del origen de su super capa:
CGRect r = CGPathGetBoundingBox(layer.path);
layer.bounds = r;
layer.position = CGPointMake(r.size.width*.5, r.size.height*.5);