2009-01-04 192 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; 
}