29

我只想将我的应用程序中的一个视图旋转到横向左侧或横向右侧。我所有其他视图都处于纵向模式,并且我已将我的应用程序设置为仅支持纵向模式。随着 iOS 6 中方向的改变,我不知道该怎么做。我已经尝试了下面发布的以下内容。谁能告诉我我做错了什么?谢谢!

-(BOOL)shouldAutorotate {
return YES;
}

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

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{

return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
} 

我也试过:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didRotate:)
                                            name:UIDeviceOrientationDidChangeNotification
                                           object:nil];
return YES;//UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
} 


 -(void)didRotate:(NSNotification *)notification {
 UIDeviceOrientation orientation = [[notification object] orientation];

if (orientation == UIDeviceOrientationLandscapeLeft) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
} else if (orientation == UIDeviceOrientationLandscapeRight) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortrait) {
    [theImage setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
    [self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
}
}
4

7 回答 7

19

这对我有用 How to force a UIViewController to Portrait orientation in iOS 6

从覆盖旋转方法的 UINavigationController 创建一个新类别:

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

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

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

@end 
于 2012-11-23T18:30:08.220 回答
6

iOS 6 在处理视图旋转方面有一些变化。支持在应用程序中定义的方向Info.plist。即使您要退回其他人。

尝试选择项目支持的所有方向。

处理视图旋转

在 iOS 6 中,您的应用程序支持在您的应用程序Info.plist文件中定义的界面方向。视图控制器可以覆盖该supportedInterfaceOrientations方法以限制支持的方向列表。一般情况下,系统只会在窗口的根视图控制器或呈现为填满整个屏幕的视图控制器上调用该方法;子视图控制器使用其父视图控制器为它们提供的窗口部分,并且不再直接参与有关支持哪些旋转的决策。应用程序的方向掩码和视图控制器的方向掩码的交集用于确定视图控制器可以旋转到哪些方向。

您可以覆盖preferredInterfaceOrientationForPresentation旨在以特定方向全屏显示的视图控制器。

在 iOS 5 和更早版本中,UIViewController该类仅以纵向模式显示视图。要支持其他方向,您必须重写该shouldAutorotateToInterfaceOrientation:方法并为您的子类支持的任何方向返回 YES。如果您的视图的自动调整大小属性配置正确,那么您可能只需要这样做。但是,UIViewController该类提供了额外的钩子供您根据需要实现额外的行为。通常,如果您的视图控制器打算用作子视图控制器,它应该支持所有界面方向。

当可见视图控制器发生旋转时,会在旋转期间调用willRotateToInterfaceOrientation:duration: willAnimateRotationToInterfaceOrientation:duration:、 和didRotateFromInterfaceOrientation:方法。viewWillLayoutSubviews在视图由其父级调整大小和定位后,也会调用该方法。如果在方向更改发生时视图控制器不可见,则永远不会调用旋转方法。但是,viewWillLayoutSubviews当视图变得可见时调用该方法。您对此方法的实现可以调用该statusBarOrientation方法来确定设备方向。

(C)苹果文档:UIViewController

于 2012-10-07T22:11:43.087 回答
2

请按照以下步骤操作

  • 创建覆盖旋转方法的 UINavigationController 的子类。
  • 在 AppDelegate 中,创建一个 BOOL islandscape属性。
  • 当视图被推送/弹出/呈现/关闭时,调整此 BOOL 值。

示例项目

我为此创建了一个示例项目,该项目运行良好。下载并集成到您的项目中:https ://www.dropbox.com/s/nl1wicbx52veq41/RotationDmeo.zip?dl=0

于 2015-07-08T05:33:56.070 回答
0

我有一个:

TabbarController -> NavigationController -> ViewController -> ViewController

我子类化UITabBarController并添加....

-(NSUInteger)supportedInterfaceOrientations{
    if (self.selectedIndex >= 0 && self.selectedIndex < 100) {
        for (id vC in [[self.viewControllers objectAtIndex:(unsigned long)self.selectedIndex] viewControllers]) {
            if ([vC isKindOfClass:[CLASS_WHICH_SHOULD_ALLOW class]]) {
                return UIInterfaceOrientationMaskPortrait + UIInterfaceOrientationMaskLandscape;
            }
        }
    }
    
    return UIInterfaceOrientationMaskPortrait;
}

于 2014-11-13T01:16:23.677 回答
0

我一直在寻找解决方案几个小时!

因此,在到处实施所需的方法之后。shouldAutorotate不需要设置,YES因为它已经设置为默认值:

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
     return UIInterfaceOrientationPortrait;
}

当需要显示UIViewController哪个需要与其他视图不同的方向时,我在UIStoryboardSegue内部创建了一个具有此实现的:

#import "Showing.h"

@implementation Showing

- (void)perform{
    NSLog(@"Showing");
    UIViewController *sourceVC = self.sourceViewController;
    UIViewController *presentingVC = self.destinationViewController;

    [sourceVC.navigationController presentViewController:presentingVC 
                                                animated:YES 
                                              completion:nil];
}

@end

在里面,UIStoryboard我将视图与这个 segue 连接起来(显示):

在此处输入图像描述

这很重要,您正在使用

presentViewController:animated:completion:

并不是

pushViewController:animated:

否则将无法再次确定方向。


我一直在尝试像

[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

或者这个在方向应该改变的地方,我也试着在我的自定义之前UIViewController调用它:UIStoryboardSeguespresentingViewControllerdismissViewController

[UIViewController attemptRotationToDeviceOrientation];

或者

NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"];

但没有一个人工作。当然最后一个例子不应该是一个选项,因为如果苹果会改变他们的任何 api 这可能会导致你的应用程序内部出现问题。

我也尝试使用该AppDelegate方法,并在寻找UIInterfaceOrientation实际的正确方向后始终确定该方法内部的方向,visibleViewController但有时在从一个方向切换到另一个方向时会发生崩溃。所以我仍然想知道为什么它变得如此复杂,而且似乎也没有任何文档可以正确解释它。即使遵循这部分也对我没有帮助

于 2015-03-31T11:47:19.983 回答
0

UIViewController+OrientationPermissions.h

@interface UIViewController (OrientationPermissions)
   + (void)setSupportedOrientations:(UIInterfaceOrientationMask)supportedOrientations;
   + (UIInterfaceOrientationMask)supportedOrientations;
@end

UIViewController+OrientationPermissions.m

@implementation UIViewController (OrientationPermissions)
static UIInterfaceOrientationMask _supportedOrientations;

+ (void)setSupportedOrientations:    (UIInterfaceOrientationMask)supportedOrientations {
    _supportedOrientations = supportedOrientations;
}

+ (UIInterfaceOrientationMask)supportedOrientations {
    return _supportedOrientations;
}

@end

在您的 UIApplication 委托中

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return [UIViewController supportedOrientations];
}

然后在所需的视图控制器上执行类似的操作

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [UIViewController setSupportedOrientations:UIInterfaceOrientationMaskAll];
}

在离开这个视图控制器之前不要忘记重置掩码

请注意,如果您使用的是 UINavigationController 或 UITabBarController,请参阅https://stackoverflow.com/a/28220616/821994如何绕过它

于 2017-05-02T08:34:18.837 回答
-2

挑战工作请尝试。2天后解决

//AppDelegate.m - 不幸的是,此方法在 iOS6 之前不可用

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m - 返回你想为每个 UIViewController 支持的任何方向

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}
于 2015-01-31T07:06:14.960 回答