7

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

例如,我有两个视图控制器,第一个是 Welcome,第二个是 Home。我希望第一个视图控制器只能是 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;
}

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

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

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

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

PPRevealSidePanel 子类 - 在此处输入图像描述

其次,我收到一个错误,试图在实际的视图控制器上更新这个子类的设置器 setLandscapeOK。登录视图控制器 - 在此处输入图像描述

4

3 回答 3

2

你能检查一下下面关于使用导航控制器处理方向的线程吗

导航控制器应该自动旋转

-anoop

于 2013-02-19T10:28:46.190 回答
0

在您的情况下出现的问题是您在该 UINavigationController 子类中覆盖了 -supportedInterfaceOrientations,因此该方法永远不会传递给它的子 ViewControllers。此外,您在 viewWillAppear 中声明了一个新的 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 中重写这些方法,你甚至不需要这个子类。你不需要做任何其他事情。您也可以在所有 ViewController 中删除该 setLandscapeOK 布尔值。

于 2013-02-13T23:50:49.080 回答
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:

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

于 2013-02-07T22:47:50.530 回答