简体   繁体   中英

Rotating view controllers within a hierarchy of Tab Bar Controller -> Navigation Controller -> View Controller

My app has a view controller hierarchy set up like this:

UITabBarController
    |
    UINavigationController
    |  |
    |  UIViewController
    |
    UINavigationController
       |
       UIViewController

All of my view controllers that are within this hierarchy override the method:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation

and return YES - therefore the view controller should be able to rotate to any rotation - even upside down.

However, within this setup none of the view controllers successfully rotate. I was under the impression that navigation and tab bar controllers would rotate if their view controllers respond to rotating.

Why won't my view controllers rotate?

The only way I've been able to get them to rotate is by subclassing UINavigationController and overriding it's shouldAutorotate method, but this feels unnecessary to me and I was wondering if there's something I've missed to make this work.

Edit:

According to the User Experience Coding How-to:

If you are also using a toolbar, the view controller for each toolbar item must implement the shouldAutorotateToInterfaceOrientation: method and return YES for each of the orientations you wish to support. If you have a navigation controller for a toolbar item, the root view controller of that navigation controller must implement the shouldAutorotateToInterfaceOrientation: method and return YES.

It says 'toolbar' - but I think this is a typo and is probably supposed to be 'tab bar'.

So it seems that I'm implementing this correctly, yet my controllers still do not auto rotate.

I've run into this problem, but I can't remember the exact reason it occurred. The tab bar controller requires all of its view controllers to respond YES when asked about a particular orientation for it to rotate to that orientation.

If presented modally, it seems like it doesn't matter about the underlying VC system.

I have created a test to show this ( RotationTest on GitHub ), but it all seems to be working. Hopefully I can remember why I was failing with this one at some point.

Subclass the UITabBarController as well as the UINavigationController. It works as using xCode 4.4.

我开发了一个扩展,允许你在没有子类化UITabBarController的情况下做到这一点https://github.com/piercifani/TabBarBetterRotation

Have you tried subclassing the Tabbarcontroller and setting it as your tabbarcontroller? In there, set

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation

to

YES

The only way I've been able to get them to rotate is by subclassing UINavigationController and overriding it's shouldAutorotate method, but this feels unnecessary to me and I was wondering if there's something I've missed to make this work.

I don't know for sure if this is the wrong approach, but I would subclass the UITabBarController, sooner than the UINavigationController. Also, you can try wrapping everything in a subclassed UIViewController that implements the rotation method, but this will create the overhead of an extra view. I once tried to do rotation in an with UINavigationController, but it was not pretty. I suspect that the reason the views only rotate if you subclass the UINavigationController is that the view hierarchy will only pass the rotation if the parent rotates. If the parent doesn't rotate, the child won't. (Imagine an iPhone in a dock. The iPhone only can rotate if the dock rotates. Now, compare the dock to an iPhone case. The case can also rotate, so the iPhone will rotate too.)

It says 'toolbar' - but I think this is a typo and is probably supposed to be 'tab bar'.

I do not think that the HIG has a typo in that regard. The terms may interchangeable.

Generally, a "toolbar" is relevant to the view that contains it, and therefore should rotate with its parent view. A tab bar, however, is the "parent", so to speak, of the view controller on the screen. The view controller should therefore only rotate if the entire app rotates. This concept basically boils down to this: Which view (bar or view controller) is dependent on the other? (The tab bar is persistent, but the views change, or is the toolbar only there if the view is visible.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM