CATransform 3D con un .m34 modificado rompe la jerarquía/ordenación de vistas en iOS6, pero no la vista a la que se aplicó

Foreword, this isn't me losing a view off screen because I did the transform wrong, it's weirder.

Problem is, if I use an .m34 transform to achieve the perspective I need, the view hierarchy breaks, but remove the transform and it draws everything correctly.

Aquí hay un ejemplo.

I have a background image (subviewOne), a menu(subviewTwo), and an object on top of all of that which I apply the CATransform3D to (subviewThree).

Código simple:

CALayer *layer = subviewThree.layer;
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = -1.0 / 500;
layer.transform = perspectiveTransform;

Prior to applying this code, the view hierarchy was, and still is on iOS 5:

(bottom to top)

After applying it, I end up with:

(bottom to top still)

Now, subviewThree still has the perspective transform applied to it, and is in the correct spot, on top of everything else, same as on iOS5. However, the Menu/subviewTwo, is now hidden by the background image/subviewOne, and nothing I do will get it to be drawn on top of the subviewOne. No amount of insertSubviewAtIndex:, bringSubviewToFront, sendSubviewToBack, etc, will make the view draw correctly.

This is incredibly peculiar particularly because the views that are drawn out of order are NO having any kind of CATransform3D applied to them.

I have verified this independently in two different apps and multiple devices 6 devices. iOS5 draws everything correctly, and if I remove those four lines, everything draws correctly, but nothing I've tried on iOS 6 stops the .m34 from breaking the view ordering. It's not always as simplistic as the example I've provided, but this is the most demonstrable case I have witnessed.

Has anyone else experienced this, solved this?

Edit: More info for comment.

Yeah, typo with the extra *.

Figure there's an Imageview, QuadCurve Menu, and Textview.

I was calling the method with the .m34 in the viewDidLoad, but swapped it to the viewDidAppear real quick to check for you.

Doesn't matter. Don't get me wrong, the subviews are listed in the correct order when you call

NSLog(@"%@", [self.view.subviews description]); 

They just aren't drawn on screen correctly.

In desperation, I wrote some crazy weird code, and I discovered the following.

I can call the method that draws the menu on a 10 second delay,

[self performSelector:@selector(createQuadCurveMenu) withObject:nil afterDelay:10];

que termina en

[self.view addSubview:menu] 

As well as a totally superfluous

[self.view bringSubviewToFront:menu]

and it's still drawn behind an imageView that is set as the lowest subview in the .xib.

I have verified this two ways. I can go into the .xib and set the imageView to hidden, and running again I can see the menu, now that the imageView isn't covering it. I can also just comment out the code that applies the .m34 transform to the textView, and the menu then again correctly appears on top of the imageView. Again, none of this happens on iOS5 and iOS4.

At this point, I'm starting to think that it's a bug inside iOS6 itself, and have been waiting for the NDA to expire so I can ask here if anyone else has experienced it.

preguntado el 22 de septiembre de 12 a las 18:09

I cannot reproduce this issue, and your code sample is incorrect (a CATransform3D is a struct, not an object, and so the asterisk should not be present). I attempted with an image view and two plain UIViews, changing the transform in viewWillAppear of the view controller and logging the subviews before and after. Can you give more information about when you are changing the transform, and what sort of views you are dealing with? -

Added some more information and code to the post itself, fixed the typo. Does that help? -

1 Respuestas

Pretty sure this is an iOS 6 bug: I've blogged about it here: Error de renderizado de iOS 6: la rotación 3D hace que las capas se rendericen sin respetar la jerarquía de vistas.

Good news: You can work around the bug by setting zPositions on the affected layers: set the zPositions in increasing order of the view hierarchy. So if I've understood correctly, you want:

subviewOne.layer.zPosition = 0;
subviewTwo.layer.zPosition = 1000;
subviewThree.layer.zPosition = 2000;

Check out the blog for more info, including a link to the Open Radar version of the bug I've logged with Apple.

Also, this might be considered a duplicate of this post: Pesadilla de la jerarquía de vistas de iOS 6. It has the same bug source and solution, although the symptoms you both describe are different.

contestado el 23 de mayo de 17 a las 11:05

Thanks! Amazing to find out I'm not the only one dealing with this issue, and I think you might be spot on. I'll try out this fix a bit later tonight and get back to you. - matt foley

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.