允许不同的导航控制器视图具有不同的方向规则

时间:2013-02-07 20:24:34

标签: ios ios5 uiviewcontroller uinavigationcontroller orientation

我正在尝试遵循上一个问题,允许导航控制器视图控制器具有不同的方向规则。 Previous Question

因此,例如,我有两个视图控制器,第一个是欢迎第二个主页。我希望第一个视图控制器只能是Potrait,第二个(Home)允许端口/风景。

我不确定我是否完全理解如何完成此操作。一旦我这样做,我打算创建一个单独的项目,解释如何执行此操作并添加到Github / share上以供将来参考。

在这个特定的项目中,我正在使用侧视图控制器github项目。 PPRevealSideViewController。

我的应用代表如下:

// Then we setup the reveal side view controller with the root view controller as the navigation controller
welcomeViewController = [[MESWelcomeViewController alloc] init];
UINavigationController *navController = [[MESNavViewControllerSubClass alloc] initWithRootViewController:welcomeViewController];


self.revealSideViewController = [[PPRevealSideViewController alloc] initWithRootViewController:navController];
[self.revealSideViewController setDirectionsToShowBounce:PPRevealSideDirectionNone];
[self.revealSideViewController setPanInteractionsWhenClosed:PPRevealSideInteractionContentView | PPRevealSideInteractionNavigationBar];

//self.window.rootViewController = welcomeViewController;
self.window.rootViewController = self.revealSideViewController;
[self.window makeKeyAndVisible];

从上面你可以看到我将导航控制器子类化为MESNavViewController。这是我对此文件的负责人:

@interface MESNavViewControllerSubClass : UINavigationController {
    BOOL setLandscapeOK;
}

MESNavViewController的Imp文件:

-(void)viewDidLoad {
    NSLog(@"subclass called");
}

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if (self->setLandscapeOK) {
        // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

在我的第一个(欢迎)视图控制器中,我有以下内容:

-(void)viewWillAppear {
    BOOL setLandscapeOK = NO;
}
- (NSInteger)supportedInterfaceOrientations {
    // Restriction for the welcome page to only allow potrait orientation
    return UIInterfaceOrientationMaskPortrait;
}

在我的第二个(Home)视图控制器中,我只有以下内容:

-(void)viewWillAppear {
    BOOL setLandscapeOK = YES;
}

我所看到的是导航中的两个视图控制器都允许任一方向。我不确定我是否理解正确。希望我提供了足够的信息。

编辑----- 我更新了PPRevealSidePanel子类,它是最顶级的控制器。然后,它保持导航控制器,导航控制器又控制视图控制器。方向应由显示的视图控制器决定。

PPRevealSidePanel子类 - enter image description here

其次,我在实际的视图控制器上尝试更新此子类的setter setLandscapeOK时收到错误。 登录视图控制器 - enter image description here

3 个答案:

答案 0 :(得分:2)

您可以查看以下有关使用导航控制器处理方向的线程

NavController ShouldAutorotate

-anoop

答案 1 :(得分:0)

您的viewWillAppear方法是否被调用?实际方法是- (void)viewWillAppear:(BOOL)animated

除此之外,问题是在viewWillAppear之前调用supportedInterfaceOrientations。尝试在initWithNibName方法中设置BOOL标志。

编辑:

类似的东西:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.setLandscapeOK = YES;
    }
    return self;
}

编辑2:

我刚刚注意到你在viewWillAppear中将setLandscapeOK重新声明为一个新变量。这是隐藏您的超类的该变量的实例。尝试使用self.setLandscapeOK而不是BOOL setLandscapeOK

编辑3:

由于您没有对主导航控制器进行子类化,因此上述内容无法正常工作。您需要一种明确的方式来通知您的导航控制器,它的子视图不希望它支持某些方向。当您按下仅为纵向的viewcontroller时,setLandscapeOK应设置为NO。

答案 2 :(得分:0)

在您的情况下出现的问题是您在UINavigationController子类中重写了--supportedInterfaceOrientations,因此该方法永远不会传递给其子ViewControllers。您还在viewWillAppear中声明了一个新的setLandscapeOK BOOL,而不是更改全局的setLandscapeOK BOOL。有点奇怪的是,基于您发布的代码,您的应用程序应该卡在纵向中,不允许所有方向,因为您似乎从未在UINavigationController子类中将setLandscapeOK布尔值设置为YES。

但是你似乎让事情变得复杂得多。您不应该需要setLandscapeOK布尔值,并且您不需要为旋转问题子类化UINavigationController或PPRevealSideViewController。 PPRevealSideViewController和UINavigationController都是容器ViewControllers,也就是包含子ViewControllers的父ViewControllers。默认情况下,在父ViewController上调用方向回调时,它将调用并返回子ViewController的相同方法。

当在PPRevealSideViewController上调用-shouldAutoRotate,-supportedInterfaceOrientations或-shouldAutoRotateToInterfaceOrientation时,它将在其rootViewController上调用相同的方法,在您的情况下是UINavigationController。 UINavigationController也是一个容器ViewController,它将在当前可见的ViewController上调用相同的方法,在你的情况下是WelcomeViewController或HomeViewController。

因此,您需要做的就是在WelcomeViewController(仅返回肖像)和HomeViewController(全部返回)中覆盖-supportedInterfaceOrientations和-shouldAutoRotateToInterfaceOrientation。不要在MESNavViewController中覆盖这些方法,你甚至不需要这个子类。你不需要做任何其他事情。您也可以在所有ViewControllers中删除setLandscapeOK布尔值。