众所周知CALayer的zPosition等效于在Z轴上做了个偏移Transform。所以我们可以通过3D Transform来视觉化各个CALayer的zPosition。
如下代码,在一个CALayer中加入多个子Layer,然后分别设置他们的zPosition:
//=== ViewController中的viewDidLoad方法中 ===
//主Layer
CGRect frame = CGRectInset(self.view.bounds, 50, 50);
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];
运行:
在没有经过任何Transform的2D环境下,zPosition仅仅会决定谁覆盖谁,具体差值是没有意义的,但是经过3D Transform,他们之间的差值,也就是距离,会显现出来。
在上面代码后加入3D 旋转Transform代码:
//Identity transform
CATransform3D transform = CATransform3DIdentity;
//Perspective 3D
transform.m34 = -1.0 / 700;
//旋转
transform = CATransform3DRotate(transform, M_PI / 3, 0, 1, 0);
//设置CALayer的sublayerTransform
layer.sublayerTransform = transform;
再次运行,如图:
注意:
从图中可以看出来,最上的文字,也就是CATextLayer在变换后会被后面的椭圆所覆盖,这个是不正确的。这或许是CATextLayer的Bug。
另外关于3D旋转变化,如果不设置上面的m34属性,整个变化结束后不会有那种透视效果。如下图:
其次注意3D Transform是设置在父CALayer的sublayerTransform属性上的,而不是transform属性。因为Transform需要设置给每个子Layer,而如果设置transform属性的话,会把整个Layer当做一个整体去变换,如下图:
或者也可以使用CATransformLayer。