0

In order to perform a flip animation with one image changing into another, I have a two-layer UIView (tried also UIView with two subviews - the same problem) rotating around X (or Y) axis in 3D.

When rotation angle is below pi/2 the top layer hides bottom layer which is OK, however with angle between pi/2 and pi I expect to see the bottom layer.

In fact the top layer is always seen no matter of the rotation angle, though both layers are all right, as if I hide top layer, I can see the bottom layer all the way.

It looks like a stiff design from Apple, or maybe I miss something. So far I have to do the animation manually for nothing better available.

This is the (simplified) code for someone who may wish to try:

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
})
cyanide
  • 3,885
  • 3
  • 25
  • 33
  • Unclear what you're trying to do. It sort of seems like flipping over a playing card to reveal its back: is that a good analogy? – matt Mar 22 '18 at 23:17
  • @matt; Yes they are trying to do that. @OP: `[UIView transitionWithView:duration:options:animations:completion:]` which allows you to specify "flip" animation to flip the view from front to back.. – Brandon Mar 23 '18 at 01:32

1 Answers1

0

Found the solution. A spite has two images, the top image has positive Z at start and negative Z at end (Tried zPosition for two-layer view - nope!):

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
})
cyanide
  • 3,885
  • 3
  • 25
  • 33