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

Posted

技术标签:

【中文标题】在 Objective-C 中的 iOS 6 上强制横向方向【英文标题】:Force Landscape Orientation on iOS 6 in Objective-C 【发布时间】:2012-12-14 03:30:36 【问题描述】:

我有一个位于 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 子类化以使其工作,或者考虑如何正确子类化和推送我的详细视图控制器。如果导航控制器无法将我的详细视图控制器从纵向推到横向,我也可以模态显示我的详细视图控制器。我哪里做错了?

【问题讨论】:

这正是我的想法:***.com/questions/11610819/… 【参考方案1】:

考虑: 视图 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);

【讨论】:

【参考方案2】:

在这方面,他们在 iOS 6 中搞砸了。到目前为止,这是我想出的:

首先,Apple 在 Xcode 4.5 中添加了“支持的界面方向”按钮。这对应于 _info.plist 中的“支持的界面方向”属性。必须先将这些按钮切换到正确的选项,然后才能使用其余按钮。 (如果按钮似乎拒绝切换,可能是因为 info.plist 被 CVS 或其他进程锁定。)

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

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

尽管使用 shouldAutorotate 禁用了自动旋转,但如果显示 MPMoviePlayerViewController,它将自动旋转。只有切换受支持的界面方向按钮才会出现这种情况。

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

【讨论】:

以上是关于在 Objective-C 中的 iOS 6 上强制横向方向的主要内容,如果未能解决你的问题,请参考以下文章

如何在linux系统上强改Root 密码

如何从Javascript调用Objective-C方法并将数据发送回iOS中的Javascript?

Objective-c:在 ios 11 更新 swrevealcontroller 中的黑色状态栏后

从 iOS 中的私钥派生的证书(Objective-C)

Objective-C 中的 iOS 10 富媒体推送通知(媒体附件)

iOS:Objective-C 中的事件监听器相当于啥?