Domanda

Esistono metodi per trasferire un CGPoint da una UIView a un'altra e da un CALayer a un altro. Non riesco a trovare un modo per cambiare un CGPoint da un sistema di coordinate di UIView a un sistema di coordinate di CALayer.

Un layer e la sua vista host hanno lo stesso sistema di coordinate? Devo trasformare i punti tra loro?

Grazie, Corey

[EDIT]

Grazie per la risposta! È difficile trovare informazioni sulle differenze / somiglianze tra CA su iPhone e Mac. Sono sorpreso di non riuscire a trovare questo problema risolto direttamente in alcuna documentazione Apple.

Stavo cercando questa risposta per aiutare con un bug che sto risolvendo, e questa è stata finora la mia ipotesi migliore, ma suppongo che sto abbaiando sull'albero sbagliato. Se i sistemi di coordinate sono uguali, allora ho un altro problema ...

Il vero problema che sto riscontrando può essere trovato qui su StackTranslate.it: solo test hit hit layer strato di ritorno quando viene toccata la metà inferiore del livello

È stato utile?

Soluzione

È possibile impostare la proprietà transform di CALayers sulla trasformazione appropriata se si desidera capovolgere il loro sistema di coordinate, ma si noti che questo probabilmente capovolgerà il loro disegno del contenuto anche (non l'ho provato, ma ha senso che questo sia vero). La mia affermazione che il CALayer associato a un UIView condivide lo stesso sistema di coordinate potrebbe in effetti essere del tutto errata. Potrebbe anche essere che i CALayer utilizzino lo stesso sistema di coordinate di UIViews (ovvero non vengano mai capovolti verticalmente), ma ho pensato che lo fossero poiché CoreGraphics utilizza un sistema di coordinate capovolto rispetto a UIKit.

Un modo semplice per testare sarebbe quello di aggiungere un CALayer di dimensioni dello schermo come sublayer del livello di una vista, quindi aggiungere un altro piccolo CALayer come sublayer di quello. Puoi impostarlo in modo che venga visualizzato su (0, 0, 320, 100) e vedere se viene visualizzato nella parte superiore o inferiore dello schermo dell'iPhone. Questo ti dirà in quale direzione va l'asse Y per CoreAnimation.

- (void)viewDidLoad {
  [super viewDidLoad];
  CALayer *rootLayer = [CALayer layer];
  rootLayer.frame = self.view.layer.bounds;
  CALayer *smallLayer = [CALayer layer];
  smallLayer.frame = CGRectMake(0, 0, rootLayer.bounds.size.width, 50);
  smallLayer.backgroundColor = [UIColor blueColor].CGColor;
  [rootLayer addSublayer:smallLayer];
  [self.view.layer addSublayer:rootLayer];
}

Ho appena eseguito questo test da solo e sembra che i CALayer utilizzino effettivamente lo stesso sistema di coordinate delle UIVview, quindi la mia affermazione che il ribaltamento dell'asse Y di CALayer è decisamente sbagliata. Tuttavia, se disegni direttamente con CoreGraphics, tieni presente che CoreGraphics utilizza utilizza un asse Y capovolto (anche se quando disegni in una sottoclasse UIView o, suppongo, un delegato CALayer, il contesto CoreGraphics è già stato capovolto per abbinare il sistema di coordinate di UIView (o CALayer).

Quindi la risposta breve, se hai raggiunto questo traguardo, è che il sistema di coordinate per CALayer dovrebbe corrispondere al sistema di coordinate per la sua UIView corrispondente.

Altri suggerimenti

La documentazione per hitTest dice:

/* Returns the farthest descendant of the layer containing point 'p'.
 * Siblings are searched in top-to-bottom order. 'p' is in the
 * coordinate system of the receiver's superlayer. */

Quindi devi fare (qualcosa del genere):

CGPoint thePoint = [touch locationInView:self];
thePoint = [self.layer convertPoint:thePoint toLayer:self.layer.superlayer];
CALayer *theLayer = [self.layer hitTest:thePoint];

In termini di documentazione Apple, ho trovato una "Nota del sistema operativo iPhone" nella sezione Layer Coordinate System di Guida alla programmazione di animazioni di base (13/11/2008).

  

Il livello radice predefinito di un'istanza UIView utilizza un sistema di coordinate capovolto che corrisponde al sistema di coordinate predefinito di un'istanza UIView & # 8211; l'origine è in alto a sinistra e i valori aumentano in basso e a destra. I livelli creati mediante l'istanza di CALayer utilizzano direttamente il sistema di coordinate standard di animazione di base.

Dai miei test ho scoperto che i sottolivelli condividono lo stesso sistema di coordinate del livello principale e quindi se si aggiunge il sottostrato a un livello UIView, condivideranno lo stesso sistema di coordinate.

Nel caso in cui desideri ancora invertire il sistema di coordinate in modo che la sua origine sia nell'angolo in alto a sinistra, dovresti usare questa trasformazione che inverte l'asse y. (x, y, 1) = (x ', y', 1) * [1 0 0], [0 -1 0], [0 altezza 1]

che tradotto in codice è: [your_layer setAffineTransform: CGAffineTransformMake (1,0,0, -1,0, altezza)];

Credo che il sistema di coordinate di una UIView e il suo livello associato dovrebbero essere gli stessi. Tuttavia, se si creano livelli da soli, il sistema di coordinate viene capovolto verticalmente.

Methods that fixing frames and points
- (CGRect) fixRect:(CGRect)rect inRect:(CGRect)container
{
    CGRect frame = rect;
    frame.origin.y = container.size.height - frame.origin.y - frame.size.height;
    return frame;
}
- (CGPoint) fixPoint:(CGPoint)point fromPoint:(CGSize)containerSize
{
    CGPoint frame = point;
    frame.y = size.height - frame.y;
    return frame;
}

Credo che i due abbiano lo stesso sistema di coordinate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top