开发者

Rotate some UIViews, but not all?

I'm doing an app where I have a GLES view which I don't want to be auto-rotated, and UIKit views on top of that, which do need to be auto-rotated.

Apparently this is not something you're supposed to be doing, as I can't find any good documentation on it. However I'm totally sure this is exactly what I want.

I've found a solution, but it feels hacky:

  1. Create window.
  2. Create some auto-rotated UIViewControllers.
  3. Add their views to the window.
  4. Create an OpenGL ES view controller that's not auto-rotated.
  5. Add its view to the window.
  6. Call bringSubviewToFront: for the auto-rotated views.
  7. Give yourself a high-five, while trying to ignore the nagging feeling that this is actually a nasty hack.

Anyone know of a better solution? NB: I'm absolutely positive that I want to auto-rotate th开发者_运维知识库e UIKit views and not the GL view.

Thanks for your time, much appreciated. =)


I've come up with a different strategy for a similar situation. In my case I allow all the views to rotate, but then use a transform to bring the view I want to keep steady back to its original orientation. This works because the "non-rotating" view is square, but with a bit more math it could work for other shapes as well. Here's what I put in my willRotateToInterfaceOrientation:duration:

switch (toInterfaceOrientation) {
    case UIInterfaceOrientationPortrait:
        steadyView.transform = CGAffineTransformIdentity;
        break;
    case UIInterfaceOrientationLandscapeLeft:
        steadyView.transform = CGAffineTransformMakeRotation(M_PI_2);
        break;
    case UIInterfaceOrientationPortraitUpsideDown:
        steadyView.transform = CGAffineTransformMakeRotation(M_PI);
        break;
    case UIInterfaceOrientationLandscapeRight:
        steadyView.transform = CGAffineTransformMakeRotation(3*M_PI_2);
        break;
}

The steadyView is s subview of the controller. This seems to do the trick.


There isn't a good way to do this any better than what you proposed.

Are you sure you don't just want to rotate the OpenGL views too? If your application is limited to the ES 2.0 devices and later on iOS 4.2, there is no longer any performance penalty to using UIViewController rotation for OpenGL views.


Wouldn't it be simpler to just draw your OpenGL content sideways when rotated? Just apply a rotation in your renderer to undo the rotation of OpenGL view.

You may see an unacceptable jump back to the original rotation, but you could address that easily. You could animate the return rotation, once the view is finished rotating. Or you could override willAnimateFirstHalfOfRotationToInterfaceOrientation:duration: and willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration: to animate the content staying in place during the interface rotation.


So I found out how it works behind the scenes; Frogblast is right, there isn't any substantially better way to do it.

What happens is that when a view gets added to a window that has no subviews, that view's controller is automatically the "rotation authority"; If that view controller returns NO from shouldAutorotateToInterfaceOrientation, no other views will rotate either. However, subsequent views (with controllers) added to the window are still allowed not to rotate, even if the "rotation authority" does rotate.

Unclear to me why they've made it like this, but there you have it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜