众所周知CALayer的zPosition等效于在Z轴上做了个偏移Transform。所以我们可以通过3D Transform来视觉化各个CALayer的zPosition。

如下代码,在一个CALayer中加入多个子Layer,然后分别设置他们的zPosition:

//=== ViewController中的viewDidLoad方法中 ===

//Layer

CGRect frame = CGRectInset(self.view.bounds5050);

CALayer *layer = [CALayer layer];

layer.frame = frame;

[self.view.layer addSublayer:layer];

 

//文字

CATextLayer *textLayer = [CATextLayer layer];

textLayer.contentsScale = [UIScreen mainScreen].scale;

textLayer.string = @"mgen 123";

textLayer.foregroundColor = [UIColor blackColor].CGColor;

textLayer.frame = layer.bounds;

textLayer.zPosition = 80;

[layer addSublayer:textLayer];

 

//第一个椭圆

CAShapeLayer *shapeLayer = [CAShapeLayer layer];

shapeLayer.contentsScale = [UIScreen mainScreen].scale;

CGMutablePathRef path = CGPathCreateMutable();

CGPathAddEllipseInRect(path, NULL, layer.bounds);

shapeLayer.path = path;

shapeLayer.fillColor = [UIColor blueColor].CGColor;

shapeLayer.zPosition = 40;

[layer addSublayer:shapeLayer];

 

//第二个椭圆

CAShapeLayer *shapeLayer2 = [CAShapeLayer layer];

shapeLayer2.contentsScale = [UIScreen mainScreen].scale;

CGMutablePathRef path2 = CGPathCreateMutable();

CGPathAddEllipseInRect(path2, NULL, layer.bounds);

shapeLayer2.path = path2;

shapeLayer2.fillColor = [UIColor greenColor].CGColor;

shapeLayer2.zPosition = 0;

[layer addSublayer:shapeLayer2];

 

//背景矩形

CALayer *backLayer = [CALayer layer];

backLayer.contentsScale = [UIScreen mainScreen].scale;

backLayer.backgroundColor = [UIColor grayColor].CGColor;

backLayer.frame = layer.bounds;

backLayer.zPosition = -40;

[layer addSublayer:backLayer];

 

运行:

屏幕快照 2013-11-25 下午3.36.50

在没有经过任何Transform的2D环境下,zPosition仅仅会决定谁覆盖谁,具体差值是没有意义的,但是经过3D Transform,他们之间的差值,也就是距离,会显现出来。

在上面代码后加入3D 旋转Transform代码:

//Identity transform

CATransform3D transform = CATransform3DIdentity;

//Perspective 3D

transform.m34 = -1.0 / 700;

//旋转

transform = CATransform3DRotate(transform, M_PI / 3010);

//设置CALayersublayerTransform

layer.sublayerTransform = transform;

 

再次运行,如图:

屏幕快照 2013-11-25 下午3.44.11

 

注意:

从图中可以看出来,最上的文字,也就是CATextLayer在变换后会被后面的椭圆所覆盖,这个是不正确的。这或许是CATextLayer的Bug。

另外关于3D旋转变化,如果不设置上面的m34属性,整个变化结束后不会有那种透视效果。如下图:

屏幕快照 2013-11-25 下午4.12.09

 

其次注意3D Transform是设置在父CALayer的sublayerTransform属性上的,而不是transform属性。因为Transform需要设置给每个子Layer,而如果设置transform属性的话,会把整个Layer当做一个整体去变换,如下图:

屏幕快照 2013-11-25 下午4.15.36

或者也可以使用CATransformLayer。