iOS 6 auto rotate confusion

╄→尐↘猪︶ㄣ 提交于 2019-11-30 05:57:15

In your Navigation Controller subclass, forward the decision to the top view controller in the stack:

-(NSUInteger) supportedInterfaceOrientations {
   return [self.topViewController supportedInterfaceOrientations];
}

Creating a separate storyboard file for this is the worst path to follow, it'll be a maintenance nightmare to keep them in sync with your app updates.

You should watch the WWDC'2012 videos especially the ones in the "Essentials" section talking about rotations.

The one called "T Evolution of View Controllers in iOS" explains the subject about rotations (and how to make them compatible with various iOS version) in great details, with explanations and code samples, and I couldn't explain it better than Apple ;)

Well i kinda hacked my way around this one. here is my Subclassed NavController.h

#import "RootVC.h"

@implementation RootVC

-(BOOL)shouldAutorotate {
    def = [NSUserDefaults standardUserDefaults];
    return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
    if ([def integerForKey:@"Should Rotate"] == 1) {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskPortrait;
}
@end

I just set an integer for @"Should Rotate" in defaults on each View Controller in

- (void)viewWillAppear:(BOOL)animated

works like a charm!

If you are using a native rootViewController, you have to extend it to support iOS5 gracefully. This is said in the above mentioned WWDC video.

Basically, if you are using a UINavigationViewController, extend it and override its - (NSUInteger)supportedInterfaceOrientations method. In there, look into your children (you can just query the older methods for interface orientation you have) and determine what should be supported and return the correct value.

The reason you need to do this to be backward compatible is 2 things: - they've deprecated the old way of rotating stuff - only rootViewController ever gets the rotation call. The parent should decide for its children what orientation it needs to be in. All these changes are inline with the new AutoLayout stuff.

After you extend your nav controller, go to your storyboard -> select the root controller (navigation controller in this case) -> set the class to your newly written class.

HTH

Here's a hack I used to support both iOS 5 devices and iOS 6 devices (as well as iPhone 5). In your prefix file, add the following #define

#ifdef __IPHONE_6_0 // Only do the rotation fix if we are building with iOS 6 API
@protocol DeprecatedRotationSupported
@optional
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation;
- (BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
@end

#define shouldAutorotateToInterface_fixed shouldAutorotate \
{ \
    UIViewController <DeprecatedRotationSupported> *selfTyped = (UIViewController <DeprecatedRotationSupported> *) self; \
\
    if(![self respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) \
        return NO; \
    int optionCount = 0; \
    for(UIInterfaceOrientation orientation = UIInterfaceOrientationPortrait; orientation <= UIDeviceOrientationLandscapeLeft; orientation++) \
    { \
        if(![selfTyped shouldAutorotateToInterfaceOrientation:orientation]) continue; \
        if(optionCount==1) return YES; \
        optionCount++; \
    } \
    return NO; \
} \
\
- (NSUInteger)supportedInterfaceOrientations \
{ \
    UIViewController <DeprecatedRotationSupported> *selfTyped = (UIViewController <DeprecatedRotationSupported> *) self; \
\
    if(![self respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) return UIInterfaceOrientationMaskPortrait; \
    \
    NSUInteger supported = 0; \
    \
    if([selfTyped shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortrait]) supported |= UIInterfaceOrientationMaskPortrait; \
    if([selfTyped shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeLeft]) supported |= UIInterfaceOrientationMaskLandscapeLeft; \
    if([selfTyped shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight]) supported |= UIInterfaceOrientationMaskLandscapeRight; \
    if([selfTyped shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortraitUpsideDown]) supported |= UIInterfaceOrientationMaskPortraitUpsideDown; \
    return supported;  \
} \
\
- (BOOL)shouldAutorotateToInterfaceOrientation
#else // We are building with the older API, leave shouldAutorotateToInterfaceOrientation alone.
#define shouldAutorotateToInterface_fixed shouldAutorotateToInterfaceOrientation
#endif // __IPHONE_6_0

Then, anywhere you use shouldAutorotateToInterfaceOrientation: instead use shouldAutorotateToInterface_fixed:

Here is my Subclassed RootNavController.h

-(BOOL)shouldAutorotate
{
    return YES;
}
-(NSUInteger) supportedInterfaceOrientations
{
    if (self.topViewController.view.superview)
    {
        return [self.topViewController supportedInterfaceOrientations];
    }

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