如何在 iOS 6 中以编程方式更改设备方向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12650137/
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
How to change the device orientation programmatically in iOS 6
提问by uttam
In iOS 5we could change the device orientation programmatically like so:
在iOS 5 中,我们可以像这样以编程方式更改设备方向:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
But in iOS 6setOrientation
is deprecated, how may i change the device orientation programmatically in iOS 6?
但是在iOS 6setOrientation
中已弃用,如何在iOS 6 中以编程方式更改设备方向?
回答by Lukasz 'Severiaan' Grela
Here are my "five cents", tested on iOS7 with ARC
这是我的“五美分”,在 iOS7 上用 ARC 测试过
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:@"orientation"];
This doesnt generate "leak" warning as performSelector will.
这不会像 performSelector 那样产生“泄漏”警告。
UIAlertView- with this code, when you open UIAlertView during view(will/Did)appear you will notice that all but this view is in portrait (apple, really?) I wasn't able to force the view to reorient but found that if you put slight delay before opening the UIAlertView then view has time to change orientation.
UIAlertView- 使用此代码,当您在视图(will/Did)出现期间打开 UIAlertView 时,您会注意到除此视图之外的所有视图都是纵向的(苹果,真的吗?)我无法强制视图重新定向,但发现如果在打开 UIAlertView 之前稍微延迟,然后视图有时间改变方向。
NoteI'm releasing my app week commencing 12/09/2014 and I will update post if it will pass or fail.
请注意,我将从 2014 年 9 月 12 日开始发布我的应用程序周,如果它通过或失败,我将更新帖子。
回答by Bala
This does not answer how to change the device Orientation, but an additional information that might help you.
这不回答如何更改设备方向,而是提供可能对您有帮助的附加信息。
iOS 6 UI Interface Orientation - shouldAutorotateToInterfaceOrientation: Not Working
iOS 6 UI 界面方向 - shouldAutorotateToInterfaceOrientation:不工作
The method shouldAutorotateToInterfaceOrientation: is NOT supported in iOS 6. Its deprecated. Just in case if you are a newbie, who just stared working in cocoa, and wondering why is your view controller messed up in iOS 6 and perfect in iOS 5, just know that shouldAutorotateToInterfaceOrientation: is not supported anymore. Even though it may work well with Xcode 4 to 4.3 it will NOT work on Xcode 4.5.
方法shouldAutorotateToInterfaceOrientation: 在 iOS 6 中不受支持。它已弃用。以防万一,如果你是一个刚开始研究可可的新手,想知道为什么你的视图控制器在 iOS 6 中搞砸了,而在 iOS 5 中却是完美的,只要知道shouldAutorotateToInterfaceOrientation: 不再受支持。尽管它可能适用于 Xcode 4 到 4.3,但不适用于 Xcode 4.5。
Apple provides a new method to get this thing done, in a much cleaner fashion. You use supportedInterfaceOrientationsinstead. It returns all of the interface orientations that the view controller supports, a mask of interface orientation values.
Apple 提供了一种以更简洁的方式完成这件事的新方法。您可以使用supportedInterfaceOrientations。它返回视图控制器支持的所有界面方向,界面方向值的掩码。
UIInterfaceOrientationMask Enum:
UIInterfaceOrientationMask 枚举:
These constants are mask bits for specifying a view controller's supported interface orientations.
这些常量是用于指定视图控制器支持的界面方向的掩码位。
typedef enum {
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
UIInterfaceOrientationMaskLandscape =
(UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
UIInterfaceOrientationMaskAll =
(UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
UIInterfaceOrientationMaskAllButUpsideDown =
(UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
UIInterfaceOrientationMaskLandscapeRight),
} UIInterfaceOrientationMask;
Using shouldAutorotateToInterfaceOrientation: method:
使用 shouldAutorotateToInterfaceOrientation: 方法:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscapeRight(toInterfaceOrientation);
}
Using supportedInterfaceOrientations method:
使用 supportedInterfaceOrientations 方法:
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
These are the added methods to UIViewController regarding Orientation in iOS6
这些是添加到 UIViewController 关于 iOS6 中的方向的方法
Added methods to UIApplication regarding Orientation in iOS6
向 UIApplication 添加了关于 iOS6 中方向的方法
回答by P.L.
I found out that the easiest way to force the device to change orientation is to present a new view controller (using presentViewController:animated:completion:
) where the new view controller specified a particular preferred orientation (by implementing the method -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
).
我发现强制设备改变方向的最简单方法是呈现一个新的视图控制器(使用presentViewController:animated:completion:
),其中新的视图控制器指定一个特定的首选方向(通过实现 方法-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
)。
When a new view controller is presented, as expected, the orientation will change to the one preferred by the new view controller. So, simplest implementation (best practice?) will be to embed all functionality you needed in a specific orientation into a separate view controller, and present it as needed. The system will take care of changing the orientation for you.
当出现一个新的视图控制器时,正如预期的那样,方向将更改为新视图控制器首选的方向。因此,最简单的实现(最佳实践?)是将特定方向所需的所有功能嵌入到单独的视图控制器中,并根据需要呈现。系统将负责为您更改方向。
Obviously this might not suit all use cases, but, fortunately the same trick is applicable to force the device to change orientation for existing view controller.
显然这可能不适合所有用例,但幸运的是,同样的技巧适用于强制设备改变现有视图控制器的方向。
The trick is to present a new view controller with the specific preferred orientation that you needed, and then hide it immediately. This will cause the orientation to change temporary when the new view controller is presented. The best part is, when the new view controller is dismissed, the original (presenting) view controller's preferredInterfaceOrientationForPresentation
is queried again, you can specify the final orientation you want here.
诀窍是呈现一个具有您需要的特定首选方向的新视图控制器,然后立即将其隐藏。当新的视图控制器出现时,这将导致方向暂时改变。最好的部分是,当新的视图控制器被关闭时,preferredInterfaceOrientationForPresentation
再次查询原始(呈现)视图控制器的 ,您可以在此处指定您想要的最终方向。
One important thing to look out here is to also temporary disable auto rotation in the original view controller (when coming back from the newly presented-then-dismissed view controller), so that when user rotate their phone towards the new orientation, it does not triggered further auto rotation.
这里需要注意的一件重要事情是临时禁用原始视图控制器中的自动旋转(当从新呈现然后关闭的视图控制器返回时),这样当用户将手机向新方向旋转时,它不会触发进一步的自动旋转。
The following code should illustrate my point, my example forces rotation to portrait, just change accordingly if you want other orientation.
以下代码应该说明我的观点,我的示例强制旋转为纵向,如果您想要其他方向,只需相应地更改即可。
Assuming you have the original view controller named Original
, and a temporary view controller named ForcePortrait
假设您有一个名为 的原始视图控制器Original
,以及一个名为的临时视图控制器ForcePortrait
@interface Original : UIViewController
{
BOOL orientationToPortrait; //should set to NO by default
}
@end
@implementation Original
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation
{
if(orientationToPortrait)
{
//when we manually changed, show in Portrait
return UIInterfaceOrientationPortrait;
}
else
{
//before manual orientation change, we allow any orientation
return self.interfaceOrientation;
}
}
-(BOOL) shouldAutorotate
{
//we should 'lock' the rotation once we manually change it
return !orientationToPortrait;
}
-(void) changeOrientationToPortrait
{
//Sample method to change the orientation
//when called, will show (and hide) the temporary view
//Original.preferredInterfaceOrientationForPresentation will be called again after this method
//flag this to ensure that we tell system we prefer Portrait, whenever it asked again
orientationToPortrait = YES;
//presenting the following VC will cause the orientation to temporary change
//when the new VC is dismissed, system will ask what is our (Original) orientation preference again
ForcePortrait* forcePortrait = [[ForcePortrait alloc] init];
[self presentViewController:forcePortrait animated:NO completion:^{
[forcePortrait dismissViewControllerAnimated:NO completion:nil];
}];
}
@end
@interface ForcePortrait : UIViewController
@end
@implementation ForcePortrait
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
@end
回答by Bissy
Try this:
尝试这个:
#import <objc/message.h>
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)){
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
}
}
回答by Bissy
You should place[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
in your AppDelegate didFinishLaunchingWithOptions
Method.
您应该放置[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
在您的 AppDelegatedidFinishLaunchingWithOptions
方法中。
Then, anywhere in your application you can get the current orientation with:
然后,您可以在应用程序的任何位置获取当前方向:
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
And test orientation with:
并测试方向:
UIInterfaceOrientationIsPortrait(orientation)
UIInterfaceOrientationIsLandscape(orientation)
as, like
作为,像
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
// code for landscape orientation
// OR
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
// OR
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];
}
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
{
// code for Portrait orientation
// OR
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortraitUpsideDown];
// OR
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
回答by Raul Quispe
This code is for iOS 8 or later
此代码适用于 iOS 8 或更高版本
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
回答by Shauket Sheikh
@implementation UINavigationController (autorotate)
@implementation UINavigationController(自动旋转)
-(NSUInteger)supportedInterfaceOrientations
{
//make the check for iphone/ipad here
if(IPHONE)
{
return UIInterfaceOrientationMaskPortrait;
}
else
{
return UIInterfaceOrientationMaskLandscape;
}
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
回答by Perisheroy
A little modification to Bissy's answer, if you want to avoid using Runtime Library:
如果您想避免使用运行时库,请对 Bissy 的答案稍作修改:
if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation]))
{
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
{
int orientationPortrait = UIInterfaceOrientationPortrait;
NSMethodSignature *sig = [[UIDevice currentDevice] methodSignatureForSelector:@selector(setOrientation:)];
NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig];
[invo setTarget:[UIDevice currentDevice]];
[invo setSelector:@selector(setOrientation:)];
[invo setArgument:&orientationPortrait atIndex:2];
[invo invoke];
}
}
回答by ppVen
This works for iOS7, force autorotate to portrait.
这适用于 iOS7,强制自动旋转到纵向。
//In your viewController.m
#import <objc/message.h>
// for autorotate viewController to portraid
- (void)viewWillAppear:(BOOL)animated {
UIInterfaceOrientation orientationStatusBar =[[UIApplication sharedApplication] statusBarOrientation];
switch (orientationStatusBar) {
case UIInterfaceOrientationPortrait:break;
case UIInterfaceOrientationLandscapeLeft:
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait);
break;
case UIInterfaceOrientationLandscapeRight:
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait);
break;
default:
break;
}
}
// this permit autorotate
- (BOOL) shouldAutorotate
{
// this lines permit rotate if viewController is not portrait
UIInterfaceOrientation orientationStatusBar =[[UIApplication sharedApplication] statusBarOrientation];
if (orientationStatusBar != UIInterfaceOrientationPortrait) {
return YES;
}
//this line not permit rotate is the viewController is portrait
return NO;
}
NOTE: I implemented this option in my app, but probably would get rejected by Apple (comment for Austin for edited 6 of Sergey K. in oct 2012).
注意:我在我的应用程序中实现了这个选项,但可能会被 Apple 拒绝(奥斯汀评论 2012 年 10 月编辑的 Sergey K. 6)。
回答by Aleksander Azizi
Apple made changing the device orientation programmatically in ios6quite difficult (on purpose mind you).
Apple 在ios6 中以编程方式更改设备方向非常困难(请注意)。
As far as I know the only way to accomplish what you're asking is to simulate the change of device orientation.
据我所知,完成您所要求的唯一方法是模拟设备方向的变化。
Using setTransform
to rotate the UIView
and re-applying its own frame gives the desired results.
使用setTransform
旋转UIView
并重新应用其自己的框架可提供所需的结果。
[YourView setTransform:CGAffineTransformMakeRotation(1.57)];
[YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];
And when the device physical orientation changes we can undo the transformation.
当设备物理方向发生变化时,我们可以撤消转换。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[YourView setTransform:CGAffineTransformMakeRotation(0)];
[YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];
}