iOS: 视觉化CALayer的zPosition

本文详细介绍了CALayer的zPosition概念及其在3DTransform下的视觉化应用,通过设置不同子Layer的zPosition并结合Transform,展示了如何在2D环境下通过3D效果区分各层元素的层级关系。同时,探讨了3D旋转Transform的实现及对层级覆盖的潜在问题,并提供了关键代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

运行:

屏幕快照 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 / 3, 0, 1, 0);
//设置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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值