仅支持一种视图的不同方向 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
Support different orientation for only one view iOS 6
提问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.plist
are 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.plist
file. A view controller can override thesupportedInterfaceOrientations
method 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
preferredInterfaceOrientationForPresentation
for a view controller that is intended to be presented full screen in a specific orientation.In iOS 5 and earlier, the
UIViewController
class displays views in portrait mode only. To support additional orientations, you must override theshouldAutorotateToInterfaceOrientation:
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, theUIViewController
class 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:
, anddidRotateFromInterfaceOrientation:
methods are called during the rotation. TheviewWillLayoutSubviews
method 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, theviewWillLayoutSubviews
method is called when the view becomes visible. Your implementation of this method can call thestatusBarOrientation
method 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
方法来确定设备方向。
回答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. shouldAutorotate
doesn't need to be set to YES
because it is already set as default:
所以在到处实施所需的方法之后。shouldAutorotate
不需要设置,YES
因为它已经设置为默认值:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
When it is time to show the UIViewController
which needs the orientation different than the other views, I created a UIStoryboardSegue
with 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 UIStoryboard
I connected the views with this segue (showing):
在UIStoryboard
I 将视图与此 segue 连接起来(显示):
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 UIViewController
where the orientation should change, and I also tryied to call it inside my custom UIStoryboardSegues
before presentingViewController
and dismissViewController
:
或这一个内部的UIViewController
,其中取向应该改变,我也tryied称它为我的自定义里面UIStoryboardSegues
前presentingViewController
和dismissViewController
:
[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 AppDelegate
method and always determine the orientation inside this method after looking for the correct UIInterfaceOrientation
of the actual visibleViewController
but 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 UITabBarController
and 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;
}