2009-01-04 109 views
11

有一些方法可以將CGPoint從一個UIView轉移到另一個UIView,並從一個CALayer轉移到另一個CALayer。我無法找到將CGPoint從UIView座標系更改爲CALayer座標系的方法。將CGPoint從UIView座標系轉換爲CALayer座標系

圖層和它的主視圖是否有相同的座標系?我需要轉換它們之間的點嗎?

感謝, 科瑞

[編輯]

感謝您的回答!很難找到關於iPhone和Mac上的CA之間的差異/相似性的信息。我很驚訝我找不到任何Apple文檔中直接提到的這個問題。

我正在追求這個答案,以幫助解決我正在排除故障的錯誤,這是迄今爲止我最好的猜測,但我想我正在吠叫錯誤的樹。如果座標系統是相同的,那麼我還有一個問題...

可以在這裏找到的堆棧溢出我遇到的實際問題: layer hit test only returning layer when bottom half of layer is touched

回答

4

如果你想翻轉它們的座標系,你可以將CALayers的transform屬性設置爲適當的變換,但是請注意,這可能會翻轉他們的contents的繪圖(我沒有測試過,但它是有意義的這將是真實的)。我認爲與UIView相關的CALayer共享相同的座標系實際上可能完全是錯誤的。也可能是CALayers使用與UIViews相同的座標系(即它們從不垂直翻轉),但我認爲它們是因爲CoreGraphics使用相對於UIKit的翻轉座標系。

一個簡單的測試方法是添加一個屏幕大小的CALayer作爲視圖圖層的子圖層,然後添加另一個小CALayer作爲其子圖層。您可以將其設置爲(0,0,320,100),並查看它是否顯示在iPhone屏幕的頂部或底部。這會告訴你Y軸在哪個方向上進行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]; 
} 

我只是執行這個測試自己,似乎CALayers實際使用相同的座標系統UIViews,所以我斷言的CALayer的翻轉Y軸是絕對錯誤的。但是,如果直接使用CoreGraphics繪圖,請注意CoreGraphics 確實使用翻轉的Y軸(儘管在繪製UIView子類或我假設爲CALayer委託時,CoreGraphics上下文已翻轉以匹配UIView (或CALayer的)座標系)。

所以簡短的回答,如果你做到了這一點,CALayer的座標系應該與其對應的UIView的座標系相匹配。

+0

凱文,如果你有時間,你會介意看我在下面我列後的主線程。你似乎對此非常瞭解,並且對任何見解都非常感謝。再次感謝 – 2009-01-05 18:29:46

-2

我認爲兩者具有相同的座標系。

0

我相信UIView及其相關圖層的座標系應該是相同的。但是,如果您自己創建圖層,則座標系會垂直翻轉。

13

的則hitTest文檔說:

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

所以,你需要做的(像這樣):

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

這很奇怪,因爲`self.layer`實際上是一個根層,所以它不應該有`superlayer`。但它確實有效。謝謝! – Rizo 2013-11-07 21:56:34

1

從我的測試中我發現,子層共享相同的座標系因爲它是父層,因此如果您將子層添加到UIView層,那麼它們將共享相同的座標系。

如果您仍然想要翻轉座標系以使其原點位於左上角,則應該使用此轉換來翻轉y軸。 (X,Y,1)=(X 'Y',1)* [1 0 0],[0 -1 0],[0 heigth 1]

其轉換爲代碼是: [your_layer setAffineTransform:CGAffineTransformMake(1,0,0,-1,0,heigth)];

4

根據Apple文檔,我在Core Animation Programming Guide(2008-11-13)的圖層座標系部分找到了一個「iPhone OS註釋」。

UIView實例的默認根層使用與UIView實例的默認座標系相匹配的翻轉座標系 - 原點位於左上角,值向右下方遞增。通過實例化CALayer直接創建的層使用標準的Core Animation座標系。

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