The layer rotates on the x / y axis instead of the z axis

After creating a test project to help get answers to a related question I recently asked on SO (deleted), I ran into a different, albeit similar problem, when rotating a layer inside a custom subclass UIView

.

A video of the iPhone simulator session can be seen here .

The layer appears to rotate along the x / y axis diagonally rather than circularly around the z axis.

The code that performs the pivot is inside the set view method called setAngle:

like this:

_imageLayer.transform = CATransform3DMakeRotation(angle / 180.0 * M_PI, 0.0, 0.0, 1.0);

      

(where angle

is in degrees).

The complete Xcode project is available here .

The original SO question only shows this behavior after changing the device orientation, so it looks like there are more whitespace in my understanding than I thought (coming from OSX background and using layers many times), I didn't expect such questions).

So my question is, why don't you need a layer rotating around the z-axis?

+3


source to share


2 answers


I was about to answer, but you fired me! Anyway, here's what I was about to say (this really goes for your last point)

The main reason for the unpredictable behavior is when you set the frame property to the converted object. This cannot be done - Apple warns about this * : the frame property will return undefined results after applying the transform.

SO, you shouldn't be doing this:

 //_imageLayer.frame = layerFrame;

      

but the settings bounds

and center

properties ( position

in the case of CALayers) continue to work as expected, so you can do something like this:



   _imageLayer.bounds = (CGRect){0,0,min,min};
   _imageLayer.position = self.center;  

      


* see the documentation for the frame property in UIView:

Warning. If the transform property is not an identity transformation, the value of this property is undefined and should therefore be ignored.

+2


source


OK, this issue has now been fixed. Updated project here .

Problems identified:



  • Don't set the view frame inside the view controller viewWillLayoutSubviews

    . This could be the root cause of the problem. You do not need to perform any calculations performed in the custom method [ViewController _currentRect]

    if the autoresist mask is set to stretch the view into the border window.

  • Do not place layers in [UIView layoutSubviews]

    what is called when the layer is rotated (!!), which is ineffective. Instead, I used [UIView setBounds:]

    to compose layers. setBounds:

    is called after the device orientation has changed, but for some strange reason it is not being called on the newly created view, so I tried [UIView didMoveToSuperview]

    to call it explicitly ( self.bounds = self.bounds;

    ). Curious and curious.

  • I set the layer bounds

    and position

    instead of setting the layer frame

    when installing it , which I thought was the main reason (things started working after I did this) however I don't see how it matters and I think that it was cured as a side effect of the error mentioned in the first paragraph of the labeling . UPDATE . As pointed out in @He's answer; this one is the main reason.

I will not mark this answer as correct as I still have a painful feeling that my decision is not 100% correct.

0


source







All Articles