【问题标题】:How to force or disable interface orientation for some but not all UIViewController?如何强制或禁用某些但不是所有 UIViewController 的界面方向?
【发布时间】:2015-10-23 20:56:48
【问题描述】:

我有一个 9-10 个屏幕的应用。我将UINavigationController 嵌入到我的视图控制器中。我有几个视图控制器,我只想设置纵向:这意味着旋转设备不应该将这些视图控制器旋转到横向模式。我尝试了以下解决方案:

第一:

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

但屏幕仍会旋转为横向。

第二: 我创建了一个自定义视图控制器类为PortraitViewController,并在PortraitViewController.m中添加了以下代码

@interface PortraitViewController ()
@end

@implementation PortraitViewController
- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    //Here check class name and then return type of orientation
    return UIInterfaceOrientationMaskPortrait;
}
@end

之后我将PortraitViewController.h 实现为基类

#import <UIKit/UIKit.h>
#import "PortraitViewController.h"
@interface Login : PortraitViewController
@end

它根本不起作用,仍然允许视图控制器在横向模式下旋转。

还有其他解决方案我正在使用 iOS 8 并且不希望 viewcontroller 在横向模式下旋转吗?

编辑: 是否可以仅对某些视图控制器具有横向方向,并强制其他视图控制器方向坚持纵向?

【问题讨论】:

  • 前两行你在哪里写的?
  • 在 ViewDidLoad@iAnurag
  • @JulianM 发布了正确答案。但是,您在应用程序的连贯性方面承担了一些风险,因为隐藏的视图控制器不会收到方向更改消息。您应该考虑重新设计您的界面并微调您的用户体验,
  • @TechGuy 你还有什么问题吗

标签: ios objective-c iphone ipad rotation


【解决方案1】:

尝试对您正在使用的UINavigationController 进行子类化,因为默认的UINavigationController 不会将shouldAutorotate 方法转发给您的视图控制器。

在您的UINavigationController 子类中实现以下方法

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

现在UINavigationController 将方法调用转发到其当前可见的UIViewController,因此您需要单独实现shouldAutorotate 以获得您想要的效果。

【讨论】:

    【解决方案2】:

    您的 PortraitViewController 没问题,但我不知道您的 Storyboard 配置。在您的情况下,重要的是您应该将目标视图控制器嵌入另一个新的导航控制器中,然后将它的类设置为您的 PortraitViewController 并以模态方式呈现该导航,就像我在下图中所做的那样,它按预期工作。

    If you want to show animation that will make presentation animation like push animation

    下面是我的 UINavigationController 的 PortrateNavigation 子类

    PortrateNavigation.h

    #import <UIKit/UIKit.h>
    
    @interface PortrateNavigation : UINavigationController
    
    @end
    

    PortrateNavigation.m

    #import "PortrateNavigation.h"
    
    @implementation PortrateNavigation
    
    - (void)viewDidLoad  {
        [super viewDidLoad];
    }
    
    - (BOOL)shouldAutorotate {
        return YES;
    }
    
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskPortrait;
    }
    
    @end
    

    【讨论】:

      【解决方案3】:

      尝试将此方法与shouldAutorotate supportedInterfaceOrientations 一起添加

      - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
          //Setting the orientation of the view.  I've set it to portrait here.
          return UIInterfaceOrientationPortrait;
      
      }
      

      您也可以使用此[UIViewController attemptRotationToDeviceOrientation] 使其旋转到所需的新方向

      【讨论】:

        【解决方案4】:

        UINavigationController 上创建一个类别并覆盖supportedInterfaceOrientations

        #import "UINavigationController+Orientation.h"
        
         @implementation UINavigationController (Orientation)
        
        -(NSUInteger)supportedInterfaceOrientations
        {
           return [self.topViewController supportedInterfaceOrientations];
        }
        
        -(BOOL)shouldAutorotate
         {
            return YES;
         }
        
        @end  
        

        当你嵌入UINavigationController时,容器不会问他们的孩子是否旋转

        【讨论】:

          【解决方案5】:

          您必须手动完成。所有视图控制器,在您不想旋转视图的视图控制器中,实现以下方法。

          - (BOOL)shouldAutorotate
          {
              return NO;
          }
          

          【讨论】:

          • 我需要设置一些委托来使用这个方法吗?
          • 不需要设置委托,是UIViewController类方法。
          • 如果视图嵌入在 uinavigation 控制器中,则应将导航子类化并在自定义导航控制器中编写该代码
          【解决方案6】:

          在你的视图控制器中处理这个

          - (BOOL)shouldAutorotate{
              return NO;
          }
          
          - (NSUInteger)supportedInterfaceOrientations{
              return UIInterfaceOrientationPortrait |
                     UIInterfaceOrientationPortraitUpsideDown;
          }
          
          - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
              return UIInterfaceOrientationPortrait;
          }
          

          【讨论】:

            【解决方案7】:

            1) 在 AppDelegate 中创建一个布尔变量。

            2) 然后在 AppDelegate.m 中复制并粘贴以下代码(根据您的要求进行修改)

            -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{NSLog(@"%d", [UIDevice currentDevice].orientation)
            
            if (self.isLandscape == YES) //bool created in first step
            {
                return  UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
            }
            
            return UIInterfaceOrientationMaskPortrait;
            }
            

            3) 现在将以下代码复制并粘贴到您要为其强制定向的视图控制器的 viewWillAppear 方法中。

            [AppDelegate sharedAppDelegate].isLandscape = YES; //bool created in first step
             NSNumber *value1 = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight]; //change the orientation as per your requirement
            [[UIDevice currentDevice] setValue:value1 forKey:@"orientation"];
            

            4) 现在在推送这个视图控制器之前,你需要先设置布尔值。所以,假设你要推送 ABC 视图控制器

            [AppDelegate sharedAppDelegate].isLandscape = YES;
            [self.navigationController pushViewController:<ABC view controller instance> animated:NO];
            

            希望这会有所帮助!

            【讨论】:

            • 'supportedInterfaceOrientationsForWindow:'的返回类型不应该是'UIInterfaceOrientationMask'而不是'NSUInteger'吗?
            • @CharlieScott-Skinner 是的。你可以在那里写。但正如定义所暗示的那样,'typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask)' 你也可以输入 NSUInteger。
            【解决方案8】:
            class ViewController: UIViewController {
                override func shouldAutorotate() -> Bool {
                    return false
                }
            }
            

            以下是该主题的链接: http://koreyhinton.com/blog/lock-screen-rotation-in-ios8.html

            【讨论】:

            • 简短的解释会改善您的答案。
            【解决方案9】:

            如果您想暂时禁用自动旋转,请避免操作方向蒙版来执行此操作。相反,覆盖初始视图控制器上的 shouldAutorotate 方法。在执行任何自转之前调用此方法。如果返回 NO,则旋转被抑制。

            因此,您需要继承“UINavigationController”,实现 shouldAutorotate 并在情节提要中使用导航控制器类。

            - (BOOL)shouldAutorotate
            
            {
            
            id currentViewController = self.topViewController;
            
            
             if ([currentViewController isKindOfClass:[DetailViewController class]])
                return NO;
            
            return YES;
            

            }

            另一种方法可以在

            上找到

            http://www.sebastianborggrewe.de/only-make-one-single-view-controller-rotate/

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2023-03-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-01-22
              相关资源
              最近更新 更多