仅支持一种视图的不同方向 iOS 6

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12772749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:38:40  来源:igfitidea点击:

Support different orientation for only one view iOS 6

objective-ciosxcode

提问by Alex G

I want to rotate ONLY one of my views within my app to either landscape left or landscape right. All my other views are in portrait mode and I have set my app to support only portrait mode. With orientation being changed in iOS 6, I am not sure how to do this. I have tried the following posted below. Can anyone tell me what I am doing wrong? Thanks!

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

-(BOOL)shouldAutorotate {
return YES;
}

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

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{

return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
} 

I have also tried:

我也试过:

-(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)];
}
}

采纳答案by ChavirA

This worked for me How to force a UIViewController to Portrait orientation in iOS 6

这对我有用 How to force a UIViewController to Portrait 在 iOS 6 中

Create a new category from UINavigationController overriding the rotating methods:

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

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

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

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

@end 

回答by Nekto

There are changes in iOS 6 regarding handling view rotations. Onlyorientations defined in apps Info.plistare supported. Even if you are returning other ones.

iOS 6 中有关于处理视图旋转的变化。Info.plist支持应用程序中定义的方向。即使你正在返回其他人。

Try to select all orientations as supported in your project.

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

Handling View Rotations

In iOS 6, your app supports the interface orientations defined in your app's Info.plistfile. A view controller can override the supportedInterfaceOrientationsmethod to limit the list of supported orientations. Generally, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen; child view controllers use the portion of the window provided for them by their parent view controller and no longer participate in directly in decisions about what rotations are supported. The intersection of the app's orientation mask and the view controller's orientation mask is used to determine which orientations a view controller can be rotated into.

You can override the preferredInterfaceOrientationForPresentationfor a view controller that is intended to be presented full screen in a specific orientation.

In iOS 5 and earlier, the UIViewControllerclass displays views in portrait mode only. To support additional orientations, you must override the shouldAutorotateToInterfaceOrientation:method and return YES for any orientations your subclass supports. If the autoresizing properties of your views are configured correctly, that may be all you have to do. However, the UIViewControllerclass provides additional hooks for you to implement additional behaviors as needed. Generally, if your view controller is intended to be used as a child view controller, it should support all interface orientations.

When a rotation occurs for a visible view controller, the willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration:, and didRotateFromInterfaceOrientation:methods are called during the rotation. The viewWillLayoutSubviewsmethod is also called after the view is resized and positioned by its parent. If a view controller is not visible when an orientation change occurs, then the rotation methods are never called. However, the viewWillLayoutSubviewsmethod is called when the view becomes visible. Your implementation of this method can call the statusBarOrientationmethod to determine the device orientation.

处理视图旋转

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

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

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

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

(C) Apple Docs: UIViewController

(C)苹果文档:UIViewController

回答by pkc456

Follow the below steps

请按照以下步骤操作

  • Create subclass of UINavigationController overriding the rotating methods.
  • In AppDelegate, create a BOOL islandscapeproperty.
  • When a view is pushed/poped/present/dismiss, adjust this BOOL value.
  • 创建覆盖旋转方法的 UINavigationController 的子类。
  • 在 AppDelegate 中,创建一个 BOOL islandscape属性。
  • 当视图被推/弹出/呈现/关闭时,调整此 BOOL 值。

Sample Project

示例项目

I created a sample project for this which is working perfectly. Download and integrate in your project: https://www.dropbox.com/s/nl1wicbx52veq41/RotationDmeo.zip?dl=0

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

回答by Aleksey Mazurenko

UIViewController+OrientationPermissions.h

UIViewController+OrientationPermissions.h

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

UIViewController+OrientationPermissions.m

UIViewController+OrientationPermissions.m

@implementation UIViewController (OrientationPermissions)
static UIInterfaceOrientationMask _supportedOrientations;

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

+ (UIInterfaceOrientationMask)supportedOrientations {
    return _supportedOrientations;
}

@end

In your UIApplication delegate

在您的 UIApplication 委托中

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

Then on a desired view controller do something like

然后在所需的视图控制器上做类似的事情

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

Don't forget to reset mask before leaving this view controller

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

Note, if you are using UINavigationController or UITabBarController, see https://stackoverflow.com/a/28220616/821994how to bypass that

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

回答by Alex Cio

I have been searching for the solution for hours!

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

So after implementing the needed methods everywhere. shouldAutorotatedoesn't need to be set to YESbecause it is already set as default:

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

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
     return UIInterfaceOrientationPortrait;
}

When it is time to show the UIViewControllerwhich needs the orientation different than the other views, I created a UIStoryboardSeguewith this implementation inside:

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

Inside the UIStoryboardI connected the views with this segue (showing):

UIStoryboardI 将视图与此 segue 连接起来(显示):

enter image description here

在此处输入图片说明

It is just important, you are using

这很重要,你正在使用

presentViewController:animated:completion:

AND NOT

并不是

pushViewController:animated:

otherwise the orientation won't be determined again.

否则将不会再次确定方向。



我一直在尝试这样的事情

[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

ORthis one inside the UIViewControllerwhere the orientation should change, and I also tryied to call it inside my custom UIStoryboardSeguesbefore presentingViewControllerand dismissViewController:

这一个内部的UIViewController,其中取向应该改变,我也tryied称它为我的自定义里面UIStoryboardSeguespresentingViewControllerdismissViewController

[UIViewController attemptRotationToDeviceOrientation];

OR

或者

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

But no one of them worked. Of course the last example shouldn't be an option, because if apple will change anything of their api this could cause problems inside your app.

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

I also tried to use the AppDelegatemethod and always determine the orientation inside this method after looking for the correct UIInterfaceOrientationof the actual visibleViewControllerbut then it sometimes happened to crash when switching from one to another orientation. So I'm still wondering why its made so complicated and there seems also not to be any documentation where it is explained correctly. Even following this part didn't helpme.

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

回答by Kurt57

I have a:

我有一个:

TabbarController -> NavigationController -> ViewController -> ViewController

TabbarController -> NavigationController -> ViewController -> ViewController

I Subclassed UITabBarControllerand add....

我子类化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;
}

回答by Ketan Patel

Defiantly work Please try. I solve after 2 days

坚决工作请尝试。我2天后解决

//AppDelegate.m - this method is not available pre-iOS6 unfortunately

//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 - return whatever orientations you want to support for each UIViewController

//MyViewController.m - 返回您希望为每个 UIViewController 支持的任何方向

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}