2009-01-04 12 views
11

Es gibt Methoden zum Übertragen eines CGPoint von einem UIView zu einem anderen und von einem CALayer zum anderen. Ich kann keine Möglichkeit finden, einen CGPoint vom UIView-Koordinatensystem in ein CALayer-Koordinatensystem zu ändern.Konvertieren eines CGPoint aus einem UIView-Koordinatensystem in ein CALayer-Koordinatensystem

Hat ein Layer und seine Host-Ansicht dasselbe Koordinatensystem? Muss ich Punkte zwischen ihnen transformieren?

Danke, Corey

[EDIT]

Danke für die Antwort! Es ist schwierig, Informationen zu den Unterschieden/Ähnlichkeiten zwischen CA auf dem iPhone und Mac zu finden. Ich bin überrascht, dass ich dieses Problem nicht direkt in einer Apple-Dokumentation finden konnte.

Ich verfolgte diese Antwort, um mit einem Fehler zu helfen, den ich bin, und das war so weit meine beste Schätzung, aber ich nehme an, dass ich den falschen Baum belle. Wenn die Koordinatensysteme gleich sind, dann habe ich ein anderes Problem ...

Die aktuelle Ausgabe kann ich habe hier auf Stack-Überlauf gefunden werden: layer hit test only returning layer when bottom half of layer is touched

Antwort

4

Sie können die transform Eigenschaft CALayers an den entsprechenden Transformation, wenn Sie ihr Koordinatensystem drehen wollen, aber beachten Sie, dass dies wahrscheinlich ihre Zeichnung der contents auch Flip wird (ich habe nicht getestet, aber es macht Sinn dass das wahr wäre). Meine Behauptung, dass der CALayer, der mit einem UIView verknüpft ist, dasselbe Koordinatensystem nutzt, könnte tatsächlich völlig falsch sein. Es könnte auch sein, dass CALayers das gleiche Koordinatensystem wie UIViews verwenden (d. H., Sie werden niemals vertikal gekippt), aber ich dachte, dies wäre der Fall, seit CoreGraphics ein gewendetes Koordinatensystem relativ zu UIKit verwendet.

Eine einfache Möglichkeit zum Testen besteht darin, einen CALayer in Bildschirmgröße als Unterschicht der Ebene einer Ansicht hinzuzufügen und dann einen weiteren kleinen CALayer als Unterschicht hinzuzufügen. Sie können festlegen, dass es bei (0, 0, 320, 100) angezeigt wird und ob es oben oder unten auf dem iPhone-Bildschirm angezeigt wird. Dies wird Ihnen sagen, in welche Richtung die Y-Achse für CoreAnimation geht.

- (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]; 
} 

Ich führte nur diesen Test selbst, und es erscheint CALayers eigentlich das gleiche System wie UIViews koordinieren verwenden, so meine Behauptung, dass CALayer der die Y-Achse drehen ist definitiv falsch. Wenn Sie jedoch direkt mit CoreGraphics zeichnen, beachten Sie, dass CoreGraphics eine umgedrehte Y-Achse verwendet (obwohl beim Zeichnen in einer UIView-Unterklasse oder, ich nehme an, ein CALayer-Delegat wurde der CoreGraphics-Kontext bereits umgedreht, um den UIViews zu entsprechen) (oder CALayers) Koordinatensystem).

Also die kurze Antwort, wenn Sie es so weit gemacht haben, ist das Koordinatensystem für CALayer sollte das Koordinatensystem für die entsprechende UIView übereinstimmen.

+0

Kevin, wenn Sie die Zeit haben, würden Sie an meinem Haupt-Thread etwas dagegen suchen unten in meinem Beitrag aufgeführt. Du scheinst ziemlich gut informiert zu sein und alle Einsichten werden geschätzt. Nochmals vielen Dank –

-2

ich glaube, die beide haben die gleiche Koordinatensystem.

0

Ich glaube, dass das Koordinatensystem eines UIView und seiner zugehörigen Schicht identisch sein sollte. Wenn Sie jedoch selbst Layer erstellen, wird das Koordinatensystem vertikal gespiegelt.

13

Die Dokumentation für hitTest sagt:

/* 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. */ 

So was Sie tun müssen (so etwas wie dieses):

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

Dies ist seltsam, weil "self.layer" eigentlich eine root-Ebene ist, also sollte es keinen "superlayer" haben. Aber es funktioniert tatsächlich. Vielen Dank! – Rizo

1

Aus meinen Tests habe ich herausgefunden, dass Unterschichten das gleiche Koordinatensystem gemeinsam nutzen Da es sich um eine übergeordnete Ebene handelt und Sie daher einer UIView-Ebene Sublayer hinzufügen, verwenden sie dasselbe Koordinatensystem.

Falls Sie das Koordinatensystem immer noch so spiegeln möchten, dass sich der Ursprung in der oberen linken Ecke befindet, sollten Sie diese Transformation verwenden, die die y-Achse kippt. (x, y, 1) = (x 'y', 1) * [1 0 0], [0 -1 0], [0 heigth 1]

, die auf Code übersetzt wird: [your_layer setAffineTransform: CGAffineTransformMake (1,0,0, -1,0, Höhe)];

4

In Bezug auf Apple-Dokumentation fand ich eine "iPhone OS Note" im Layer Coordinate System Abschnitt der Core Animation Programming Guide (2008-11-13).

Der standardmäßige Root-Layer einer UIView-Instanz verwendet ein gewendetes Koordinatensystem, das dem Standardkoordinatensystem einer UIView-Instanz entspricht. Der Ursprung befindet sich oben links und Werte werden nach unten und rechts erhöht. Layer, die durch die Instanziierung von CALayer erstellt werden, verwenden das Standard-Core-Animations-Koordinatensystem.

0
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; 
}