CATransform3D 旋转导致一半图像消失

发布于 2024-10-18 10:05:28 字数 454 浏览 1 评论 0原文

我使用以下代码来旋转图像,但已旋转到页面“之外”的图像的一半(沿 y 轴向下)消失了。如何修复? heading 以弧度为单位。

    CALayer *layer = myUIImageView.layer;
    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform.m34 = 1.0 / 500;
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, heading, 0.0f, 1.0f, 0.0f);
    layer.transform = rotationAndPerspectiveTransform;

I'm using the following code to rotate an image, but half the image (down the y-axis) that has been rotated "out of" the page, disappears. How to fix? heading is in radians.

    CALayer *layer = myUIImageView.layer;
    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform.m34 = 1.0 / 500;
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, heading, 0.0f, 1.0f, 0.0f);
    layer.transform = rotationAndPerspectiveTransform;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

紧拥背影 2024-10-25 10:05:28

解决方案是适当设置所有图层的 zPosition 属性。感谢 @Brad Larson,他在此处的评论中建议了此解决方案。看来,当您开始使用 CATransform3D 时,由 addsubview 建立的正常 zindex 视图层次结构将被抛出窗口。

The solution to this was to set the zPosition property of all my layers appropriately. Thanks is due to @Brad Larson, who suggested this solution in a comment here. It seems that, when you start using CATransform3D, the normal zindex view hierarchy established by addsubview is thrown out the window.

猫腻 2024-10-25 10:05:28
  layer.anchorPoint = CGPointMake(0.0, 0.0);
  layer.anchorPoint = CGPointMake(0.0, 0.0);
要走干脆点 2024-10-25 10:05:28

anchorPoint 设置为 {0.0, 0.0} 也可以(正如 Liam 已经指出的那样)。

以下是更改 anchorPoint 而不更改图层在屏幕上的位置的完整代码片段:

     layer.anchorPoint = CGPointMake( 0.0, 0.0 );

     CGPoint position = layer.position;
     CGSize size = layer.bounds.size;

     CGFloat posX = position.x - size.width / 2.0;
     CGFloat posY = position.y - size.height / 2.0;

     layer.position = CGPointMake( posX, posY );

Setting the anchorPoint to {0.0, 0.0} works as well (as Liam already pointed out).

Here's the full code snippet for changing the anchorPoint without changing the layer's position on screen:

     layer.anchorPoint = CGPointMake( 0.0, 0.0 );

     CGPoint position = layer.position;
     CGSize size = layer.bounds.size;

     CGFloat posX = position.x - size.width / 2.0;
     CGFloat posY = position.y - size.height / 2.0;

     layer.position = CGPointMake( posX, posY );
凉墨 2024-10-25 10:05:28

为了防止其他人陷入困境,我最终通过大幅膨胀其他增量层之间的“z 空间”来解决这个问题。

考虑三个视图A、B和C,位置为A->B。 B-> C 在其父视图中。

每个视图在父视图中的索引是该视图的实际位置。通过获取这些值,我们会发现视图 A 的位置为 0,视图 B 的位置为 1,依此类推。

为了解决消失/剪切问题,我通过将每个视图的位置乘以任意大的值来为每个视图分配 zPosition:

viewA.layer.zPosition = (0 + 1) * 5000
viewB.layer.zPosition = (1 + 1) * 5000
viewC.layer.zPosition = (2 + 1) * 5000

解释

想象一个 100 像素宽的视图 B 旋转 12 度进入屏幕。这会导致视图 B 的左半部分消失在视图 A 下方。使用三角学,我们可以找到视图 B 的“深度”:

sin(12°) × 100px2 = 10.39px ~ 10.4 px

这意味着视图 A zPosition 属性需要递减 10.4,以便它不会裁剪视图 B。如果同一层次结构中视图 A 下面有任何其他视图,它们也必须类似地递减。 (或者,视图 B 和更高的视图需要将其层的 zPosition 增加 10.4。)

我发现,如果我们增加视图层之间的间隙,则不会出现需要繁琐地减少或增加层数。我选择了任意大的值 5000,因为它需要比 10,000 点更宽的视图才能突破相邻视图:sin(90°) × 10,0002 = 5000 (90度给出最大深度或高度)。

In case anyone else is stuck, I finally got around this by dramatically inflating the "z-space" between otherwise incremental layers.

Consider three views A, B, and C positioned A -> B -> C inside their parent view.

Each view's index inside the parent view is the de facto position for that view. By grabbing those values, we'd find that that view A has a position of 0, view B has a position of 1, and so forth.

To solve the disappearing/clipping issue, I assign zPosition to each view by multiplying its position by an arbitrarily large value:

viewA.layer.zPosition = (0 + 1) * 5000
viewB.layer.zPosition = (1 + 1) * 5000
viewC.layer.zPosition = (2 + 1) * 5000

Explanation

Imagine a 100px-wide view B rotating 12 degrees into the screen. This causes the left half of view B to disappear below view A. Using trigonometry, we can find how "deep" view B goes:

sin(12°) × 100px2 = 10.39px ~ 10.4 px

That means the view A zPosition property needs to be decremented by 10.4 so that it doesn't clip view B. If you have any other views below view A in the same hierarchy, they would also have to be similarly decremented. (Alternatively, view B and higher views would need to have their layers' zPosition incremented by 10.4.)

I found that if we increase the gaps between view layers, there is no need to tediously decrement or increment the layers. I chose an arbitrarily large value of 5000 because it would take a view wider than 10,000 pts to breakthrough neighbouring views: sin(90°) × 10,0002 = 5000 (90 degrees gives the maximum depth or height).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文