8

I've implemented this method in my code to know when an interface orientation change will occur:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

I rely on this to be called to setup my views. In either iOS 4 or 5 it gets called properly when the orientation changes.

In iOS 4 it also gets called when the controller first loads (regardless of if the orientation changes or not, it gets called once at the beginning with the correct orientation).

The problem is I noticed in iOS 5 this does not happen anymore. The method gets called when the orientation changes but not when the controller initially loads. This is a problem for me because I rely on this to setup the initial view placement based on the orientation.

Any ideas why this behaviour changed? What's the best way to handle this? Should I check what the orientation is in viewDidLoad if on iOS 5 and then manually call the willRotate and didRotate methods? This feels a bit like a hack.

Thanks for any input you can provide.

nebs
  • 4,939
  • 9
  • 41
  • 70

4 Answers4

15

Since I'm pressed for time I've had to work around this odd behaviour and manually call the orientation methods in viewDidLoad. This is a bit of a hack but it's working fine so far.

In viewDidLoad I added this:

if ( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0") ) {
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self willRotateToInterfaceOrientation:interfaceOrientation duration:0.2f];
}

I've then added this in a common header file:

// iOS Version Checking
#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

I got the iOS version checking defines from an answer to this question on SO.

Community
  • 1
  • 1
nebs
  • 4,939
  • 9
  • 41
  • 70
1

Since iOS 5 and higher you should build you view controllers hierarchy (using -addChildViewController:). Then child view controllers begin to call -willRotateToInterfaceOrientation:interfaceOrientation: and other interface related methods again (because parent controller will notify them about UI orientation changes).

Please, do not use any 'dirty' methods.

Useful documentation: Apple docs about 'addChildViewController:'

Vladlex
  • 845
  • 8
  • 16
1

Even I faced a similar issue and had to override it in the tabbarcontroller derived class to get this to work:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [_tabBarConroller willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

Hope this helps!!

Verbeia
  • 4,400
  • 2
  • 23
  • 44
Ramanand
  • 11
  • 1
1

I've run into this same problem and have been pulling my hair out. I've finally discovered a solution but unfortunately this will be iOS 5.0 + only:

Place the following code in your viewDidLoad method in your custom UIViewController:

double delayInSeconds = 0.1f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [UIViewController attemptRotationToDeviceOrientation];
});

This will push the rotation update to the next run loop. attemptRotationToDeviceOrientation is an iOS 5.0+ call.

Maurizio
  • 4,143
  • 1
  • 29
  • 28