2011-12-29 11 views
15

In breve:Impostazione corretta cornice di una nuova creazione CAShapeLayer

  1. Apple non impostare il frame o bounds per un CAShapeLayer automaticamente (e Apple ha non implementato un equivalente di [UIView sizeThatFits])
  2. Se si imposta la frame usando le dimensioni del riquadro di delimitazione del percorso ... tutto va storto. Non importa come si tenta di impostare, esso viti-su per il sentiero

Allora, qual è il modo corretto di impostare a livello di codice la cornice di una nuova creazione CAShapeLayer con un appena aggiunto CGPath? I documenti di Apple sono silenziosi sull'argomento.

Le cose che ho provato, che non funzionano:

  1. Creare un CAShapeLayer
  2. Creare un CGPath, aggiungerlo al layer
  3. Controllare del frame livello - è {{0,0},{0,0}}
  4. Set: layer.frame = CGPathGetBoundingBox(layer.path)
  5. Il frame ora è corretto, ma il percorso è ora DOPPIO offset - modifica del frame fa sì che il percorso in modo efficace spostare un extra (x,y) pixel

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

  7. ... tutto va noci. Niente più senso
  8. Provare a risolverlo facendo layer.position = CGPathGetBoundingBox(layer.path).origin
  9. ... senza dadi; ancora pazzo.

Una cosa che ho provato che ha funzionato, ma causa problemi altrove:

EDIT: Questo rompe non appena si auto-rotazione dello schermo. La mia ipotesi: la rotazione automatica di Apple richiede il controllo della proprietà "transform".

  1. Creare un CAShapeLayer
  2. Creare un CGPath, aggiungerlo al layer
  3. Controllare fotogramma del livello - è {{0,0},{0,0}}
  4. Set: 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

Questo funziona, ma ... un sacco di codice di terze parti presuppone che la trasformazione iniziale f oppure a CALayer è Identità.

Non dovrebbe essere così difficile! Sicuramente c'è qualcosa che sto facendo di sbagliato qui?

(Ho ricevuto un suggerimento: "ogni volta che aggiungi un percorso, esegui manualmente una funzione personalizzata per spostare tutti i punti di -1 * (top-left-point.x, top-left-point.y)".Ancora una volta, funziona - ma è ridicolmente complesso)

+0

Hai mai trovato una soluzione a questo? – jannej

+0

Non ancora. Attualmente sto usando la soluzione alternativa dalla domanda stessa. È lento ed è doloroso da mantenere. Penso che il problema sia un bug nel codice di Apple, forse? – Adam

+3

Una piccola aggiunta: alla fine ho scoperto che ".frame" non è supportato da Apple. Questo è bizzarro, perché è usato ovunque - ma se si approfondisce abbastanza nei documenti e/o nelle mailing list di Apple, si scoprono note dagli ingegneri Apple che dicono che non è destinato a funzionare e che non risolveranno bug con esso. È previsto/richiesto l'uso di .bound per TUTTO, e trattare .frame come "readonly". Quindi è particolarmente ironico che in questo caso l'impostazione .frame "quasi funziona", dove l'impostazione .bounds "non funziona mai" :) – Adam

risposta

4

L'impostazione di layer.bounds sui limiti del percorso è la cosa giusta da fare: si desidera che lo spazio delle coordinate locali del livello corrisponda al percorso. Ma devi anche impostare la proprietà della posizione del livello per spostarla nel posto giusto nel suo super strato.

(Impostazione .Frame traduce nel quadro calcolare i giusti valori di .bounds e .position per voi, ma lascia sempre bounds.origin intatto, che non è quello che si vuole quando i limiti di percorso è di origine non-zero .)

Quindi qualcosa come questo dovrebbe funzionare, a patto che non hanno cambiato l'AnchorPoint dal suo valore solito (0,5, 0,5) e si vuole posizionare lo strato a filo l'origine del suo superlayer:

CGRect r = CGPathGetBoundingBox(layer.path); 
layer.bounds = r; 
layer.position = CGPointMake(r.size.width*.5, r.size.height*.5); 
Problemi correlati