iOS 6设备方向问题

7

我有两个视图控制器。我希望第一个视图控制器只支持竖屏模式,而第二个视图控制器应支持所有方向。请帮帮我。

在AppDelegate类中,我的代码如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];
    UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    self.window.rootViewController = self.viewController;
  //  [self.window addSubview:navController.view];
    [self.window makeKeyAndVisible];   
    return YES;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSLog(@"supportedInterfaceOrientationsForWindow");
    return  UIInterfaceOrientationMaskAllButUpsideDown;
}

第一个视图控制器的代码是:

-(BOOL)shouldAutorotate
{
    return NO;
}


-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskPortrait;
}

第二个视图控制器的代码如下:

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

我要检查的是第一和第二个视图控制器是否调用了 'shouldAutorotate' 方法。

您的快速帮助将不胜感激。 谢谢。 Kashif

3个回答

8
尝试像这样为第二个UIViewController设置supportedInterfaceOrientations:
- (BOOL) shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight; // add any other you want
}

另外,在第一个UIViewController中的同一方法中仅启用纵向。

也许您需要在项目设置中启用这些方向,以便第二个UIViewController能够支持。


[编辑 #1:添加示例应用程序]

这是一个示例应用程序,希望可以解决您的问题。

AppDelegate.h

#import <UIKit/UIKit.h>

@class FirstViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) FirstViewController *viewController;

@end

AppDelegate.m

#import "AppDelegate.h"

#import "FirstViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

FirstViewController.h

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

- (IBAction)goToSecondViewController:(id)sender;

@end

FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(BOOL)shouldAutorotate
{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationMaskPortrait;
}

- (IBAction)goToSecondViewController:(id)sender
{
    SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    [self presentViewController:svc animated:NO completion:nil];
}

@end

SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

- (IBAction)goToFirstViewController:(id)sender;

@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

- (IBAction)goToFirstViewController:(id)sender
{
    [self dismissViewControllerAnimated:NO completion:nil];
}

@end

FirstViewController.xib

FirstViewController.xib

SecondViewController.xib

SecondViewController.xib


此外,在 Interface Builder 中,当您单击为第二个 UIViewController 制作的 xib 文件时,请检查其方向是否设置为横向。 - uerceg
我已经对我的答案进行了第一次编辑。请尝试并告诉我它是否适用于您。 - uerceg
1
嗨,我尝试了你的第一种解决方案,但它仍然在旋转。我还希望我的视图控制器只保持纵向方向。 - NicTesla
仍在旋转的是什么?在我的例子中,我只让第一个UIViewController保持纵向模式,而第二个UIViewController可以在任何方向上旋转。当我运行这个应用程序时,第一个UIViewController仅处于纵向模式。第二个UIViewController可以在任何方向上旋转,但这只是实现方式。您可以将其限制为您想要的方向。 - uerceg
换句话说,如果我将您的代码从:
  • (IBAction)goToSecondViewController:(id)sender
    {
    SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    [self presentViewController:svc animated:NO completion:nil];
    }
    更改为
  • (IBAction)goToSecondViewController:(id)sender
    {
    SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    [self pushViewController:svc animated:NO];
    }
    那么您将会遇到与我一样的错误输出。
- Kashif Ilyas
显示剩余5条评论

2
根据您的描述,第一个视图控制器被推入导航控制器。您的shouldAutorotatesupportedInterfaceOrientations方法定义是完全正确的。在方向变化期间,您的导航控制器的shouldRotate只会被触发,并且不会触发您的第一个视图控制器(导航控制器的子控制器)的shouldAutorotate。因此,您需要在您的视图控制器中或单独的文件中category导航控制器,并在需要的地方进行导入。以下是UINavigation Controller类别的代码。
.h文件中有以下代码:
    @interface UINavigationController (autoRotate)

-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;

@end

.m文件中有以下代码

  #import "UINavigationController+autoRotate.h"

@implementation UINavigationController (autoRotate)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

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

如果你将类别写在单独的文件中,你需要在第一个和第二个视图控制器中导入.h文件,如下所示:#import "UINavigationController+autoRotate"

0
一个简单的解决方案:
实现:- (NSUInteger)supportedInterfaceOrientations 当从AppDelegate.m中询问时, - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 更多细节已经在这里回答了: iOS 6 landscape and portrait orientation

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接