Search code examples
iphoneipadiosuitabbarcontrollerautorotate

Autorotation disabled after setting selectedIndex property of UITabBarControllers (SDK bug?)


The problem. I'm getting a very strange error in my application. I have a UITabBarController with several view controllers for the tabs. In the view controllers I have implemented autorotation via shouldAutorotateToInterfaceOrientation: and it was working fine until I made the following change.

I implemented swipe gestures in the view controllers to change between tabs. This is accomplished via the following code.

- (void)onSwipeLeft {
  int _count = [[self.tabBarController.tabBar items] count];
  int i = self.view.tag - 1;
  if (i < _count - 1) {
    self.tabBarController.selectedIndex = (i + 1) % _count;
  }
}

And similarly for onSwipeRight.

Now, autorotation only works until you swipe left or right. After that, shouldAutorotateToInterfaceOrientation: is never called at all.

See also.

  • In this thread the identical problem is described. I also sometimes see a log message like the following: -[UIWindow beginDisablingInterfaceAutorotation] overflow on <UIWindow: 0x1410e0; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x141190>>. Ignoring. I can't find any other information about this.

  • This question seems to be describing the same problem.

  • This question seems to be describing a similar problem but with popViewController:. Note that the bug has been there since SDK 3.2.

What to do? It seems like a bug in the SDK which is still present in 4.1. Has anyone found a workaround? It seems like a common scenario.


Solution

  • I should have thought of this earlier.

    Create UIWindow+ensureAutorotation.h:

    #import <UIKit/UIKit.h>
    
    @interface UIWindow (ensureAutorotation)
    
    - (void)beginDisablingInterfaceAutorotation;
    - (void)endDisablingInterfaceAutorotation;
    
    @end
    

    And UIWindow+ensureAutorotation.m:

    #import "UIWindow+ensureAutorotation.h"
    
    @implementation UIWindow (ensureAutorotation)
    
    - (void)beginDisablingInterfaceAutorotation {}
    - (void)endDisablingInterfaceAutorotation{}
    
    @end
    
    // of course this can be added as a simple category, rather than .h .m files