Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

didRotateFromInterfaceOrientation firing Twice when Rotated

I realize that didRotateFromInterfaceOrientation is deprecated in iOS 8; however, I have an app that needs to remain compatible with iOS7. The problem I am having is that when the device is rotated (iPad in this case) this method is being called twice. This happens on an actual device as well as with the simulator. I have simply put an NSLog in the method to show this.

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{

        NSLog(@"didRotateCalled");
}

I have also checked the willRotateToInterfaceOrientation but that one works correctly only getting called once.

Any thoughts why the didRotateFromInterfaceOrientation method would be fired twice per rotation?

As a quick update. I put a breakpoint in which revealed something interesting. This view is a UISplitviewcontroller and it looks like the method is called first for the UISplitviewcontroller and then as a UIViewController. Not sure why...

Some additional information. I am using Storyboards one for iPhone and the other iPad. The iPhone does not use the splitViewController. The code base is shared so in the prepareForSegue I do the following:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
            UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
            splitViewController.delegate = segue.destinationViewController;
}
like image 246
C6Silver Avatar asked Sep 30 '22 05:09

C6Silver


2 Answers

I have my answer. I just downloaded the simulators for iOS 7.1 for use within the latest Xcode. I found that the viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator method is NOT called when running under iOS 7.1. However, I also found that the issue I described with the rotation firing twice does NOT happen with the willRotateToInterfaceOrientation method in iOS7 but again it DOES in iOS 8. This is a clear bug at Apple.

It looks like I will need to detect the OS version the customer is running and if it is iOS 8 or above I will not have it execute any code in the willRotateToInterfaceOrientation method. I can, however, leave the viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator method in there for iOS 8 devices as this method will just be ignored by iOS 7.

I don't know if this is just a problem for splitviewcontrollers or for all view methods using rotation between iOS 7 and 8. If your app is not overriding this method than you'd never know. If it is you will face what I did above. Not good.

Here is the code I am using to check for version:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    if (NSFoundationVersionNumber == NSFoundationVersionNumber_iOS_7_1) // use this only for iOS7 devices as otherwise this fires twice under iOS8
    {
        ...
    }
}

I have left -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator method as this will simply be ignored by iOS 7 devices but will be called by iOS 8.x and presumably above.

like image 153
C6Silver Avatar answered Nov 15 '22 07:11

C6Silver


I have the same issue (though in my case willRotate is executed twice on iOS 8 as well). I used the following workaround:

BOOL _willRotate; // iVar for the state

// Methods that should be called from willRotate/didRotate (can be inline)
- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute
{
    if(_willRotate) {
        return NO;
    }
    _willRotate = YES;
    return YES;
}

- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute
{
    if(_willRotate) {
        _willRotate = NO;
        return YES;
    }
    return NO;
}

// Inside willRotate (return if shouldn't execute):
if(![self workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute]) {
    return;
}

// Inside didRotate (return if shouldn't execute):
if(![self workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute]) {
    return;
}
like image 20
silyevsk Avatar answered Nov 15 '22 06:11

silyevsk