在Objective-C中强制iOS 6横屏方向

7
我有一个主视图控制器,它位于UINavigationController内部。在该主视图控制器中,我有一个按钮,该按钮推送一个具有UIWebView的详细视图控制器。我希望加载此详细视图控制器时处于横屏模式。回到主视图控制器后,它会强制返回到纵向模式。我正在运行iOS 6。
我已经看过其他类似的问题,但在我的情况下不起作用。我创建了一个LandscapeViewController,它是UIViewController的子类,我在其中编写了这些方法:
#pragma mark - Orientation Methods
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotate
{
    return YES;
}

这是我在推出详细视图控制器时的代码:

DetailViewController *detailVC = [[DetailViewController alloc]
                                      initWithNibName:@"DetailViewController"
                                      bundle:nil];

    [self.navigationController pushViewController:detailVC
                                         animated:YES];

我正在考虑在上述代码中将我的LandscapeViewController子类化以使其工作,或者如何正确地子类化并推送我的详细视图控制器。如果导航控制器无法从纵向模式推送我的详细视图控制器,我也可以以模态方式呈现我的详细视图控制器。我做错了什么?


这正是我所考虑的:https://dev59.com/s2bWa4cB1Zd3GeqPWmwp?rq=1 - jaytrixz
2个回答

8

考虑到:

视图A:仅竖屏 - 视图B:仅横屏

我不能在导航控制器中实现它。相反,我打开了一个模态视图从视图A到视图B,并将一个新的导航控制器强行置于该视图。

这对我来说在iOS5+上可行。

你需要为导航控制器创建一个类别,像这样:

UINavigationController+Rotation_IOS6.h

#import <UIKit/UIKit.h> 

@interface UINavigationController (Rotation_IOS6)

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

@end

UINavigationController+Rotation_IOS6.h

#import "UINavigationController+Rotation_IOS6.h"

@implementation UINavigationController (Rotation_IOS6)

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

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

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.topViewController preferredInterfaceOrientationForPresentation];
}

@end

AppDelegate.m中添加以下内容:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    return UIInterfaceOrientationMaskAll;
}

接下来在A视图中:

- (BOOL)shouldAutorotate {
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}

同样在视图 A 中打开视图 B,请执行以下操作:

ViewB *vc = [[ViewB alloc] initWithNibName:@"ViewB" bundle:nil];

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc];

[self presentViewController:navigationController animated:YES completion:nil];

最后,在 视图B 中。
- (BOOL)shouldAutorotate {
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

0

他们在iOS 6中在此方面有点搞砸了。以下是我目前所了解到的:

首先,苹果在Xcode 4.5中添加了“支持的界面方向”按钮,这对应于_info.plist中的“Supported interface orientations”属性。在其余任何操作之前,必须将这些按钮切换到正确的选项。(如果按钮似乎拒绝切换,则可能是因为info.plist被CVS或其他进程锁定了。)

接下来,必须设置属性.window.rootViewController,并且必须指向堆栈中的“底部”视图控制器。通常这将是导航控制器或标签控制器。

如果希望禁用所有旋转,则可以使用按钮来完成,或者可以在“底部”视图控制器中实现“shouldAutorotate”方法,并使其返回NO。(如果省略该方法,则默认值为YES。)

尽管已通过shouldAutorotate禁用了自动旋转,但如果显示了MPMoviePlayerViewController,它仍将自动旋转。只有切换支持的界面方向按钮才能防止这种情况发生。

如果想要有条件地自动旋转其他视图控制器会更加复杂。基本上,您的“底部”视图控制器必须实现 supportedInterfaceOrientations 方法,并根据当前的 topViewController 返回适当的位掩码。这可以通过查询 topViewController 的旧的“shouldAutorotateToInterfaceOrientation”方法来完成,但它有点丑陋。尽管此方案不需要修改旋转视图控制器的代码,但是您仍需要修改旋转视图控制器下面的 VC 来实现 "supportedInterfaceOrientation",否则该视图将在返回时被旋转。(至少这是一个简单的复制/粘贴)似乎没有人提出更好、更通用的方案。

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