在UINavigationController下只要一个页面支持转屏

来源:互联网 发布:西安行知小学 编辑:程序博客网 时间:2024/05/22 05:32

碰到了问题,搜索了一下。还是谷歌给力


Handling Rotation in iOS6



1down votefavorite
3

I only want to support different Orientations on one View in my UINavigationController Stack. How can I do this?

It also has to work in iOS5.

share|improve this question
 

3 Answers

activeoldestvotes
up vote7down voteaccepted

I've had a lot of trouble with how iOS6 handles Orientation, hopefully this is what you're looking for.

Create an extension of UINavigationController and call it "UINavigationController+autoRotate".

Put this in your UINavigationController+autoRotate.h:

#import <UIKit/UIKit.h>@interface UINavigationController (autoRotate)-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation;-(BOOL)shouldAutorotate;- (NSUInteger)supportedInterfaceOrientations;@end

Put this in UINavigationController+autoRotate.m:

#import "UINavigationController+autoRotate.h"@implementation UINavigationController (autoRotate)-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];}- (BOOL)shouldAutorotate{    return [self.visibleViewController shouldAutorotate];}- (NSUInteger)supportedInterfaceOrientations{    if (![[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"ViewController")])    {        return UIInterfaceOrientationMaskAllButUpsideDown;    }    else    {        return [self.topViewController supportedInterfaceOrientations];    }}@end

For Views that you DO NOT want to rotate, add:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return (interfaceOrientation == UIInterfaceOrientationPortrait);}- (NSUInteger)supportedInterfaceOrientations{    return UIInterfaceOrientationMaskPortrait;}- (BOOL)shouldAutorotate{    return NO;}

And for Views you DO want to rotate:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return (interfaceOrientation != UIDeviceOrientationPortraitUpsideDown);}- (NSUInteger)supportedInterfaceOrientations{    return UIInterfaceOrientationMaskAllButUpsideDown;}- (BOOL)shouldAutorotate{    return YES;}

In your App's delegate, add:

- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window{    return UIInterfaceOrientationMaskAllButUpsideDown;}
share|improve this answer
 
 
Why implement shouldAutorotateToInterfaceOrientation: when that's a deprecated method? And is "shouldAutoRotate" spelled that way (with upper-case R) in your actual implementation? –  Hot Licks Dec 10 '12 at 20:43
 
@HotLicks To ensure compatibility with iOS5, but thanks - shouldAutorotate was a typo –  mmackh Dec 11 '12 at 8:16
 
Yes, but you're adding shouldAutorotateTo... to the nav controller and having it look up the stack. For iOS5 the top of the stack would be consulted without this added code. It seems unnecessary (and unnecessarily confusing). –  Hot Licks Dec 11 '12 at 12:04
 
FWIW, the default implementation of supportedInterfaceOrientations returns 26 -- all orientations except upside-down. So the method need not be added to VCs for which that default is sufficient. –  Hot Licks Dec 11 '12 at 12:09
 
Really helpful. It helped me and saved my time and did within very less time. –  AppAspect Apr 1 at 15:07
show 2 more comments
up vote0down vote

I recommend you to NOT create a category on UINavigationController to override those methods. Categories are not aimed to do that, and there is no warranty that your code is going to be loaded instead of Apple's one (even if actually that works). I advise you to create a subclass of UINavigationController, and override those methods in it.

share|improve this answer
 
 
From the 6.1 Beta release notes: Landscape-only apps that invoke a portrait-only view controller (such as the Game Center login screen) will cause the app to crash. Workaround: Apps should provide the delegate method application:supportedInterfaceOrientationsForWindow: and ensure that portrait is one of the returned mask values. When a UINavigationController is involved, subclass the UINavigationController and override supportedInterfaceOrientations. –  mmackh Nov 2 '12 at 7:28 


1down votefavorite
3

I only want to support different Orientations on one View in my UINavigationController Stack. How can I do this?

It also has to work in iOS5.

share|improve this question
 

3 Answers

activeoldestvotes
up vote7down voteaccepted

I've had a lot of trouble with how iOS6 handles Orientation, hopefully this is what you're looking for.

Create an extension of UINavigationController and call it "UINavigationController+autoRotate".

Put this in your UINavigationController+autoRotate.h:

#import <UIKit/UIKit.h>@interface UINavigationController (autoRotate)-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation;-(BOOL)shouldAutorotate;- (NSUInteger)supportedInterfaceOrientations;@end

Put this in UINavigationController+autoRotate.m:

#import "UINavigationController+autoRotate.h"@implementation UINavigationController (autoRotate)-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];}- (BOOL)shouldAutorotate{    return [self.visibleViewController shouldAutorotate];}- (NSUInteger)supportedInterfaceOrientations{    if (![[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"ViewController")])    {        return UIInterfaceOrientationMaskAllButUpsideDown;    }    else    {        return [self.topViewController supportedInterfaceOrientations];    }}@end

For Views that you DO NOT want to rotate, add:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return (interfaceOrientation == UIInterfaceOrientationPortrait);}- (NSUInteger)supportedInterfaceOrientations{    return UIInterfaceOrientationMaskPortrait;}- (BOOL)shouldAutorotate{    return NO;}

And for Views you DO want to rotate:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{    return (interfaceOrientation != UIDeviceOrientationPortraitUpsideDown);}- (NSUInteger)supportedInterfaceOrientations{    return UIInterfaceOrientationMaskAllButUpsideDown;}- (BOOL)shouldAutorotate{    return YES;}

In your App's delegate, add:

- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window{    return UIInterfaceOrientationMaskAllButUpsideDown;}
share|improve this answer
 
 
Why implement shouldAutorotateToInterfaceOrientation: when that's a deprecated method? And is "shouldAutoRotate" spelled that way (with upper-case R) in your actual implementation? –  Hot Licks Dec 10 '12 at 20:43
 
@HotLicks To ensure compatibility with iOS5, but thanks - shouldAutorotate was a typo –  mmackh Dec 11 '12 at 8:16
 
Yes, but you're adding shouldAutorotateTo... to the nav controller and having it look up the stack. For iOS5 the top of the stack would be consulted without this added code. It seems unnecessary (and unnecessarily confusing). –  Hot Licks Dec 11 '12 at 12:04
 
FWIW, the default implementation of supportedInterfaceOrientations returns 26 -- all orientations except upside-down. So the method need not be added to VCs for which that default is sufficient. –  Hot Licks Dec 11 '12 at 12:09
 
Really helpful. It helped me and saved my time and did within very less time. –  AppAspect Apr 1 at 15:07
show 2 more comments
up vote0down vote

I recommend you to NOT create a category on UINavigationController to override those methods. Categories are not aimed to do that, and there is no warranty that your code is going to be loaded instead of Apple's one (even if actually that works). I advise you to create a subclass of UINavigationController, and override those methods in it.

share|improve this answer
 
 
From the 6.1 Beta release notes: Landscape-only apps that invoke a portrait-only view controller (such as the Game Center login screen) will cause the app to crash. Workaround: Apps should provide the delegate method application:supportedInterfaceOrientationsForWindow: and ensure that portrait is one of the returned mask values. When a UINavigationController is involved, subclass the UINavigationController and override supportedInterfaceOrientations. –  mmackh Nov 2 '12 at 7:28