Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何绕Y轴翻转CALayer?_Ios_Core Animation_Perspective_Rotational Matrices - Fatal编程技术网

Ios 如何绕Y轴翻转CALayer?

Ios 如何绕Y轴翻转CALayer?,ios,core-animation,perspective,rotational-matrices,Ios,Core Animation,Perspective,Rotational Matrices,我在CALayer的子类中使用了这段代码,该子类的实例是根CALayer的子层 -(void)setSelected:(bool)s { selected=s; if (s) { CATransform3D rot = CATransform3DMakeRotation(M_PI, 0, 1, 0); rot.m34=-1.0 / 200; [self setTransform:rot]; } else

我在CALayer的子类中使用了这段代码,该子类的实例是根CALayer的子层

-(void)setSelected:(bool)s {
    selected=s;
    if (s)
    {
        CATransform3D  rot = CATransform3DMakeRotation(M_PI, 0, 1, 0);
        rot.m34=-1.0 / 200;
        [self setTransform:rot];

    }
    else
    {
            CATransform3D  rot = CATransform3DMakeRotation(0, 0, 1, 0);
        rot.m34=-1.0 / 200;
        [self setTransform:rot];
    }
}
当选定的属性设置为TRUE时,会发生以下情况:旋转直到角度等于M_PI/2,然后层消失,因为它是正交的。动画的结束是错误的:在动画的第一部分(例如在左侧)中显示为增长的边将在左侧而不是右侧结束动画。但是,内容被翻转了

我认为这与两个旋转矩阵之间的插值有关,但我不能确切地理解发生了什么

详细信息:动画似乎正在执行以下操作:

  • 围绕Y轴的旋转增量为+Pi/2
  • 内容翻转
  • 围绕Y轴的旋转增量为-Pi/2,就好像它从(yz)平面反弹一样
  • 翻页的内容就是我想要实现的

    以下是我得到的动画帧。正如你所见,梯形的小边总是在左边;它应该在动画末尾的右侧(右上角帧)。

    想象一下,你的图层是一块平面半透明塑料,上面投影着一个图像,因此它的两面都会发光。旋转pi/2时,它处于“边上”,因此它将消失。当旋转大于pi/2但小于pi时,平面塑料板的背面会暴露出来。因为它是半透明的,你可以看到图像的背面,但是因为你从后面看到它,它是镜像的。当角度达到pi时,板材将在y轴上翻转整整180度。它是倒置的,您可以从后面看到图像,因此它是向后的。

    变换的数学不正确。应该在旋转变换之后应用透视变换,这意味着连接两个变换。更改旋转变换的m34系数并不等效

    您应该用以下代码替换代码:

    -(void)setSelected:(bool)s {
        selected=s;
        CATransform3D perpectiveTransform = CATransform3DIdentity;
        perpectiveTransform.m34 =-1.0 / 200;
    
        if (s)
        {
    
            CATransform3D  rot = CATransform3DMakeRotation(M_PI, 0, 1, 0);
            [self setTransform:CATransform3DConcat(rot, perpectiveTransform)];
    
        }
        else
        {
            CATransform3D  rot = CATransform3DMakeRotation(0, 0, 1, 0);
            [self setTransform:CATransform3DConcat(rot, perpectiveTransform)];
        }
    }
    
    顺便说一句,应用透视变换的一种更方便的方法是使用超层的
    sublayerttransform
    属性,从而将其应用于每个子层(如果需要)

    这将产生如下结果:

    self.superlayer.sublayerTransform = perspectiveTransform;  //do this in your setup
    ....
    self.transform = rot;
    

    以获得相同的外观效果。

    如果有人只想水平翻转图像或视图的方向

    yourView.layer.transform = CATransform3DMakeScale(-1, 1, 1);
    


    有什么问题?是内容被翻转了,还是角度还是翻转的方向?第二种方法也是可能的,但在我的例子中,它不起作用,因为我只是希望每个层在自己的空间中执行3d旋转,看起来完全一样(没有因空间中的位置而变形)。我有一个橡胶垫来选择这些层,这也是一个CALayer。设置这样的变换也会变换橡皮筋,如果要使用鼠标单击在视图中的位置来绘制选择橡皮筋,则还需要取消投影。
    yourView.layer.affineTransform =  CGAffineTransformMakeScale(-1, 1);