围绕 X 或 Y 轴旋转的双层视图

A two-layer view rotating around X or Y axis

为了执行一个图像变为另一个图像的翻转动画,我有一个双层 UIView(也尝试了具有两个子视图的 UIView - 同样的问题)在 3D 中围绕 X(或 Y)轴旋转。

当旋转角度低于 pi/2 时,顶层隐藏底层,这没问题,但是角度在 pi/2 和 pi 之间,我希望看到底层。

其实顶层不管旋转多少角度都可以看到,虽然两层都可以,就像我隐藏了顶层一样,我一直看到底层。

它看起来像 Apple 的僵硬设计,或者我可能错过了什么。到目前为止,我必须手动制作动画,没有更好的可用方法。

这是为可能希望尝试的人提供的(简化)代码:

let frame = CGRect(origin: CGPoint(), size: spriteSize)

let sprite = UIView(frame: frame)
sprite.isHidden = true

let bottomLayer = CALayer()
bottomLayer.frame = frame
bottomLayer.contents = UIImage(named:"name1.png")!.cgImage
bottomLayer.transform = CATransform3DMakeScale(-1, 1, 1)
sprite.layer.addSublayer(bottomLayer)

let topLayer = CALayer()
topLayer.frame = frame
topLayer.contents = UIImage(named:"name2.png")!.cgImage
sprite.layer.addSublayer(topLayer)

parent.addSubview(sprite)

sprite.layer.position = fromPosition
sprite.isHidden = false

UIView.animate(withDuration: 3, delay: 0,
                    animations:{
    sprite.layer.transform =
            CATransform3DConcat(
                    CATransform3DMakeRotation(CGFloat.pi, 1, 0, 0))
    sprite.layer.position = targetPosition
})

找到解决方案。 spite 有两个图像,顶部图像在开始处有正 Z,在结束处有负 Z(尝试了 two-layer 视图的 zPosition - 不!):

let frame = CGRect(origin: CGPoint(), size: spriteSize)

let sprite = UIView(frame: frame)
sprite.isHidden = true

let bottomView = UIIMageView(image: UIImage(named:"name1.png"))
bottomView.frame = frame
bottomView.layer.transform = CATransform3DMakeScale(-1, 1, 1)
sprite.addSubview(bottomView)

let topView = UIImageView(image: UIImage(named:"name2.png"))
topView.frame = frame
topView.layer.transform = 
      CATransform3DMakeTranslation(0, 0, 0.5) // !!!!
sprite.addSubview(topView)

parent.addSubview(sprite)
sprite.layer.position = fromPosition
sprite.isHidden = false

UIView.animate(withDuration: 3, delay: 0, animations:{
    sprite.subviews.last!.layer.transform =
           CATransform3DMakeTranslation(0, 0, -0.5) // !!!!
    sprite.layer.transform =
            CATransform3DConcat(
                    CATransform3DMakeRotation(CGFloat.pi, 1, 0, 0))
    sprite.layer.position = targetPosition
})