Ios CALayer压扁子层

Ios CALayer压扁子层,ios,objective-c,core-animation,calayer,Ios,Objective C,Core Animation,Calayer,我正在创建一个用户界面,在这里我们有一副卡片,你可以从屏幕上刷下来 我希望能做的是创建UIView的一个子类,该子类将表示每张卡,然后修改transform属性,将它们向后(z轴)移动,再向上(y轴)移动,以获得一副卡的外观 通过阅读,我发现我需要使用CATTransferMlayer而不是普通的CALayer,这样z轴就不会变平。我创建了一个CATTransfermLayer原型,将其添加到CardDeckView的层中,然后将我的所有卡添加到该CATTransfermLayer中。代码看起来

我正在创建一个用户界面,在这里我们有一副卡片,你可以从屏幕上刷下来

我希望能做的是创建UIView的一个子类,该子类将表示每张卡,然后修改transform属性,将它们向后(z轴)移动,再向上(y轴)移动,以获得一副卡的外观

通过阅读,我发现我需要使用CATTransferMlayer而不是普通的CALayer,这样z轴就不会变平。我创建了一个CATTransfermLayer原型,将其添加到CardDeckView的层中,然后将我的所有卡添加到该CATTransfermLayer中。代码看起来有点像这样:

+ (Class) layerClass
{
    return [CATransformLayer class];
}
在init中:

// Initialize the CATransformSublayer
_rootTransformLayer = [self constructRootTransformLayer];
[self.layer addSublayer:_rootTransformLayer];
constructRootTransformLayer(角度法是多余的,本来打算调整甲板角度,但后来决定不这样做):

然后,添加卡的代码如下所示:

// Set up a CardView as a wrapper for the contentView
RVCardView* cardView = [[RVCardView alloc] initWithContentView:contentView];

cardView.layer.cornerRadius = 6.0;
if (cardView != nil) {
    [_cardArray addObject:cardView];
    //[self addSubview:cardView];
    [_rootTransformLayer addSublayer:cardView.layer];
    [self setNeedsLayout];
}
请注意,我最初想要的是简单地将RVCardView直接添加为子视图-我想要保留仅添加图层无法保存的触摸事件。不幸的是,最终发生的情况如下:

如果我将这些卡添加到rootTransformLayer,我最终会得到正确的外观,即:

注意,我尝试在根视图(CardDeckView)上使用layerClass,如下所示:

+ (Class) layerClass
{
    return [CATransformLayer class];
}

我已经确认根层类型现在是CATTransfermLayer,但我仍然得到了扁平化的外观。为了防止扁平化,我还需要做什么

使用视图时,您会看到平面场景,因为没有设置透视。要与3D图形(如OpenGL)进行比较,为了渲染场景,必须设置摄影机矩阵,该矩阵将3D世界转换为2D图像。
这是相同的:子层内容在三维空间中使用
CATransform3D
进行变换,但是,当父层
CALayer
显示它们时,默认情况下会将它们投影到x和y上,而忽略z坐标

请参阅Apple文档中的。这是您缺少的代码:

CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0 / eyePosition; // ...on the z axis

myParentDeckView.layer.sublayerTransform = perspective;
请注意,为此,您不需要使用
CATTransferMLayer
,一个简单的
CALayer
就足够了:

下面是应用于图片中的子视图的转换(
eyePosition=-0.1
):


中指出了使用
CATTransferMlayer
的原因
CALayer
将其转换的子层“光栅化”,然后应用其自身的转换,而
CatTransferMLayer
保留完整的层次结构并独立绘制每个子层;仅当具有多个级别的三维变换子图层时,此选项才有用。在您的案例中,场景树只有一个级别:甲板视图(其本身具有作为变换的标识矩阵)和卡片视图,以及子视图(它们在三维空间中移动)。因此,在这种情况下,
CATTransferMLlayer
是多余的。

使用视图时,您会看到一个平面场景,因为没有设置透视。要与3D图形(如OpenGL)进行比较,为了渲染场景,必须设置摄影机矩阵,该矩阵将3D世界转换为2D图像。
这是相同的:子层内容在三维空间中使用
CATransform3D
进行变换,但是,当父层
CALayer
显示它们时,默认情况下会将它们投影到x和y上,而忽略z坐标

请参阅Apple文档中的。这是您缺少的代码:

CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0 / eyePosition; // ...on the z axis

myParentDeckView.layer.sublayerTransform = perspective;
请注意,为此,您不需要使用
CATTransferMLayer
,一个简单的
CALayer
就足够了:

下面是应用于图片中的子视图的转换(
eyePosition=-0.1
):


中指出了使用
CATTransferMlayer
的原因
CALayer
将其转换的子层“光栅化”,然后应用其自身的转换,而
CatTransferMLayer
保留完整的层次结构并独立绘制每个子层;仅当具有多个级别的三维变换子图层时,此选项才有用。在您的案例中,场景树只有一个级别:甲板视图(其本身具有作为变换的标识矩阵)和卡片视图,以及子视图(它们在三维空间中移动)。因此,在这种情况下,
CATTransferMlayer
是多余的。

将再次检查我的代码并验证这是否有帮助。回答得很好,真的很有帮助@皮埃特罗:谢谢你的回答。但如果我想要透视模式下的视图框架,该怎么办呢?我在这种模式下使用了错误的框架。@girish_pro“视图框架”是什么意思?我不熟悉这个布局概念。也许你想改变图层的颜色?@PietroSaccardi你能回顾一下我的问题吗。如果我得到catTransferMLayer的“contents”属性,我会得到一个由所有子层组成的CGImageRef吗?我会仔细检查我的代码并验证这是否有帮助。回答得很好,真的很有帮助@皮埃特罗:谢谢你的回答。但如果我想要透视模式下的视图框架,该怎么办呢?我在这种模式下使用了错误的框架。@girish_pro“视图框架”是什么意思?我不熟悉这个布局概念。也许你想改变图层的颜色?@PietroSaccardi你能回顾一下我的问题吗。如果我得到catTransferMLlayer的“contents”属性,我会得到一个由所有子层组成的CGImageRef吗?