我遇到了一个问题,当值变大时,Core Animation似乎忽略了zPosition
的值。
这可以很容易地复制。
CGFloat largeZPosition = 1000000000;
CALayer *topLayer = ...
CALayer *bottomLayer = ...
bottomLayer.frame = CGRectOffset(topLayer.frame, 50, 50);
topLayer.zPosition = largeZPosition + 1;
bottomLayer.zPosition = largeZPosition;
// Intentionally sort the sublayers array in the wrong order.
rootLayer.sublayers = @[ topLayer, bottomLayer ];
z值位置值较小时,按预期运行。即使子层数组未正确排序,顶层也会显示在底层之上,如下所示:
但是,如上所示,结果如下:
显然这不正确。
根据我的需要,我无法对子图层数组进行手动排序,因此我依靠zPosition
按预期执行。所以我的问题是:我该如何解决这个问题?感谢。
答案 0 :(得分:12)
这是因为QuartzCore似乎正在将zPosition
转换为float
,所以当CGFloat
为double
时它会失去精确度。 IEEE单精度浮点数使用24位表示有效位和精度,因此可能无法精确表示大于2 ^ 24的整数。例如,
float largeZPosition = 1000000000;
float largeZPositionPlus1 = 1000000001;
NSLog(@"%f %f %d", largeZPosition, largeZPositionPlus1, largeZPosition == largeZPositionPlus1);
输出
1000000000.000000 1000000000.000000 1
下一个可精确表示的整数是1000000064。
请注意,CALayer.zPosition
定义为CGFloat
,只要基础CGFloat
能够做到这一点,它就能够保持大于2 ^ 24的整数值。检查
layer.zPosition = 1000000001;
NSLog(@"%f", layer.zPosition);
在64位OS X上,CGFloat
为double
,输出
1000000001.000000
所以,在CALayer
公共Objective-C类级别,精度并没有丢失。 QuartzCore还有其他地方可以转换为单精度float
。
我建议使用小于2 ^ 24的整数(包括加法结果)。鉴于zPosition
具有浮点类型,您可以使用较小的小数值而不是大的整数值。