众所周知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。