calayer cgpath cashapelayer

calayer - Configuración del marco correcto de un CAShapeLayer recién creado



cgpath (1)

En breve:

  1. Apple NO establece el frame o los bounds para un CAShapeLayer automáticamente (y Apple NO HA implementado un equivalente de [UIView sizeThatFits] )
  2. 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:

  1. Crear un CAShapeLayer
  2. Crea un CGPath , CGPath a la capa.
  3. Comprueba el frame la capa - es {{0,0},{0,0}}
  4. Establecer: layer.frame = CGPathGetBoundingBox( layer.path )
  5. 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)

  6. Establecer: layer.bounds = CGPathGetBoundingBox( layer.path )

  7. ... todo se vuelve loco. Ya nada tiene sentido
  8. Intenta arreglarlo haciendo layer.position = CGPathGetBoundingBox( layer.path ).origin
  9. ...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".

  1. Crear un CAShapeLayer
  2. Crea un CGPath , CGPath a la capa.
  3. Comprueba el marco de la capa - es {{0,0},{0,0}}
  4. Establecer: layer.frame = CGPathGetBoundingBox( layer.path )
  5. 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);