willAnimateRotationToInterfaceOrientation not called on ios6/7

半腔热情 提交于 2020-01-03 03:34:21

问题


I have an old app, that still lives on iTunes, written in iOS 5. I would like to update it to run on ios 6 and 7. Everything has been fine so far, and I have updated my code to use ARC. However when trying to maintain the same autorotation philosophy I keep hitting a brick wall. I have already checked relative topics within SO like:

Forcing landscape and autorotate in iOS 7,

Autorotate in iOS 6 has strange behaviour

and following a similar topic I have found this:

iOS 6 Autorotation Problems and Help

which lead me to do the following:

I have set the rootViewController within my AppDelegate like so:

self.preloadingViewController = [[PreloadingViewController alloc] initWithNibName:@"PreloadingViewController" bundle:nil];
self.window.rootViewController = self.preloadingViewController;

I have placed:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAllButUpsideDown;

}

within my AppDelegate. I have overriden shouldAutorotate and supportedInterfaceOrientations within the SuperViewController (parent in inheritance terms) of all of my app's UIViewControllers (including PreloadingViewController mentioned above):

- (BOOL)shouldAutorotate{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

and in every child UIViewController, I override

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

with code to layout ui elements in the desirable manner for portrait and landscape orientations.

Finally my app's plist file under

Supported interface orientations

contains:

Portrait (bottom home button), Landscape (left home button), Landscape (right home button)

all the orientations I want to support.

Still, even though supportedInterfaceOrientations and shouldAutorotate are being called for every orientation change on my rootViewController, willAnimateRotationToInterfaceOrientation is never being called. I have even overriden shouldAutomaticallyForwardRotationMethods in my SuperViewController to return YES, but to no avail.

What am I doing wrong here? Any ideas? I have even considered that the old ios5 - style xibs cause the issue but I do not think this is the case.

Thanks in advance.


回答1:


In iOS 6 the way willAnimateRotationToInterfaceOrientation is called changed.

Use:

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

    // Something
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    // Something
}

in your rootController.

EDIT:

New main.m

#import <UIKit/UIKit.h>
#import "yourAppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([yourAppDelegate class]));
    }
}



回答2:


Since my rootViewController was the only one getting its shouldAutorotate and supportedInterfaceOrientations methods called, I decided to register every other view controller to get notified of any UIDeviceOrientationDidChangeNotification.

[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];

- (void)orientationChanged:(NSNotification *)notification
{
    NSLog(@"Orientation changed!");
    [self layoutForOrientation:[[UIDevice currentDevice] orientation]];
}

Within my layoutForOrientation: method I handled the uiview's controls orientation.

However, although I did receive UIDeviceOrientationDidChangeNotification notifications normally, my view orientation would not actually change to match the current orientation, i.e. if the new orientation was say, UIInterfaceOrientationLandscapeRight, the view orientation would remain in UIInterfaceOrientationPortrait and its children views would get rotated by 90 degrees. This did certainly not look right. After pulling a lot of hair out, I decided to abandon this route.

Instead, I have set my rootViewController to be a UINavigationController and have it push successive UIViewControllers on top of it. Since I did not want a navigation bar visible in my app I have set the navigation controller's navigationBarHidden property set to YES. This way the method willAnimateRotationToInterfaceOrientation is getting called on every UIViewController that is currently at the top of the navigationCotroller's stack of controllers, and its corresponding view and view controls rotate correctly for the desired orientations.

This works because most of my view controllers supported interface orientations match the mask: UIInterfaceOrientationMaskAllButUpsideDown, the default behaviour for iPhone. Should I needed to support different orientations, I would have to subclass the UINavigationController and override supportedInterfaceOrientations and shouldAutorotate to enable the desired orientations support for the navigation stack's top view controller, as per Apple's example project: AlternateViews.




回答3:


Implement this method, return YES for what you need.

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation



来源:https://stackoverflow.com/questions/20425607/willanimaterotationtointerfaceorientation-not-called-on-ios6-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!