【问题标题】:Support different orientation for only one view iOS 6仅支持一个视图的不同方向 iOS 6
【发布时间】:2012-09-28 04:10:28
【问题描述】:

我只想将我的应用中的一个视图旋转到横向左侧或横向右侧。我所有的其他视图都处于纵向模式,并且我已将我的应用程序设置为仅支持纵向模式。随着 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)];
}
}

【问题讨论】:

  • 这个视图是否在 tabbarcontroller 中?
  • 感谢@Hackmodford 的回复。不,不是,只是一个导航控制器

标签: objective-c ios xcode


【解决方案1】:

这对我有用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 

【讨论】:

  • 我已经看到两个解决方案建议使用类别来覆盖方法 - 这肯定是一个非常糟糕的主意,因为现在整个应用程序中的所有导航控制器都将设置这些方向方法!
【解决方案2】:

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)Apple Docs: UIViewController

【讨论】:

  • 所以在我将 plist 设置为支持所有方向之后,您能否解释一下需要哪些特定代码来支持我的所有纵向视图以及仅需要横向的唯一 1 个视图?非常感谢。会接受
  • 我试过 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationMaskPortrait;在我只想要纵向的视图上,它仍然旋转到横向。这当然会发生,因为我尝试了您启用所有方向的建议
  • @AlexG 你为什么要更改该属性?据说:A view controller can override the supportedInterfaceOrientations method to limit the list of supported orientations.?覆盖supportedInterfaceOrientations 属性,仅此而已。
  • 我试过了,但应用程序崩溃并显示“支持的方向没有共同的方向”。如果我启用所有可能的方向,那么它可以工作,但只有当我将手机旋转到横向时,它不会在视图加载时自动执行,然后我的所有其他视图也不会停止旋转到横向,即使我返回 UIInterfaceOrientationMaskPortrait。还有其他建议吗?非常感谢,我真的很感激
【解决方案3】:

按照以下步骤进行

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

示例项目

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

【讨论】:

  • 看起来像BOOL island escape。应该是真的
【解决方案4】:

我有一个:

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;
}

【讨论】:

    【解决方案5】:

    我已经寻找解决方案几个小时了!

    所以在到处实现所需的方法之后。 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 连接起来(showing):

    这很重要,你正在使用

    presentViewController:animated:completion:
    

    与否

    pushViewController:animated:
    

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


    我一直在尝试像
    [UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
    

    这个在UIViewController 中的方向应该改变,我也尝试在presentingViewControllerdismissViewController 之前在我的自定义UIStoryboardSegues 中调用它:

    [UIViewController attemptRotationToDeviceOrientation];
    

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

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

    我也尝试使用AppDelegate 方法,并在寻找实际visibleViewController 的正确UIInterfaceOrientation 后始终确定此方法内的方向,但有时在从一个方向切换到另一个方向时会发生崩溃。所以我仍然想知道为什么它变得如此复杂,而且似乎也没有任何文档可以正确解释它。 甚至关注this part didn't help我。

    【讨论】:

      【解决方案6】:

      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 如何绕过它

      【讨论】:

        【解决方案7】:

        挑战工作请尝试。 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;
        }
        

        【讨论】:

          猜你喜欢
          • 2013-01-03
          • 2023-03-03
          • 1970-01-01
          • 2013-05-04
          • 2012-10-07
          • 2012-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多