在iOS 5中,我们可以通过编程方式来更改设备的方向:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
但在 iOS 6 中,setOrientation
已被弃用,我该如何在编程中更改设备方向?
在iOS 5中,我们可以通过编程方式来更改设备的方向:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
但在 iOS 6 中,setOrientation
已被弃用,我该如何在编程中更改设备方向?
这是我的“五分之一”,在具有ARC的iOS7上进行了测试。
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:@"orientation"];
performSelector 会产生“泄漏”警告,而这不会。
UIAlertView - 使用此代码,在视图(will/Did)appear期间打开UIAlertView时,您会注意到除了此视图之外,所有视图都处于纵向状态(苹果,真的吗?)。我无法强制视图重新定位,但发现如果在打开UIAlertView之前稍微延迟一下,视图就有时间改变方向。
注意:我将在2014年12月9日发布我的应用程序,如果它通过或未通过审核,我将更新帖子。
以下内容并不回答如何更改设备方向,但它是一些可能对你有帮助的额外信息。
iOS 6 UI界面方向 - shouldAutorotateToInterfaceOrientation: 不起作用
shouldAutorotateToInterfaceOrientation:方法在iOS 6中已经不再被支持。如果你是一个刚开始接触cocoa编程的新手,并且想知道为什么你的视图控制器在iOS 6中混乱而在iOS 5中完美无缺,那么请注意shouldAutorotateToInterfaceOrientation:已经不再被支持了。即使它在Xcode 4到4.3版本中运行良好,它也不会在Xcode 4.5上工作。
苹果提供了一种更加干净的方法来解决这个问题,你可以使用supportedInterfaceOrientations代替。它返回一个掩码值,表示视图控制器所支持的所有界面方向。
UIInterfaceOrientationMask枚举:
这些常量是用于指定视图控制器支持的界面方向的掩码位。
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;
使用 shouldAutorotateToInterfaceOrientation: 方法:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscapeRight(toInterfaceOrientation);
}
使用 supportedInterfaceOrientations 方法:
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
iOS6中UIViewController新增了以下关于方向的方法:
preferredInterfaceOrientationForPresentation:设置视图控制器首选呈现方向。
shouldAutorotate:指示视图控制器是否支持自动旋转。
supportedInterfaceOrientations:返回当前视图控制器支持的所有方向。
iOS6中UIApplication新增了以下关于方向的方法:
supportedInterfaceOrientationsForWindow::返回应用程序在给定窗口中所支持的所有方向。
UIInterfaceOrientationMask:定义界面支持的方向组合。
我发现强制设备改变方向的最简单方法是通过呈现新的视图控制器(使用presentViewController:animated:completion:
),其中新的视图控制器指定了特定的首选方向(通过实现方法-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
)。
当呈现一个新的视图控制器时,预期的结果是,方向将更改为新视图控制器所希望的方向。因此,最简单的实现方式(最佳实践?)是将您需要的所有功能嵌入到一个特定方向的单独视图控制器中,并根据需要呈现它。系统将为您处理方向更改。
显然,这可能不适用于所有用例,但幸运的是,同样的技巧也适用于强制设备更改现有视图控制器的方向。
技巧是呈现一个具有所需首选方向的新视图控制器,然后立即隐藏它。这会在呈现新视图控制器时导致方向临时更改。最好的部分是,当新视图控制器被解除显示时,原始(呈现)视图控制器的preferredInterfaceOrientationForPresentation
将再次查询,您可以在此处指定最终方向。
在此要注意的一个重要事项是,在从新呈现-然后解除显示的视图控制器返回时,还要临时禁用原始视图控制器中的自动旋转,这样当用户将其手机旋转到新方向时,它不会触发进一步的自动旋转。
以下代码应该说明我的观点,我的示例强制旋转为纵向,如果您想要其他方向,请相应更改。
假设您将原始视图控制器命名为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
试试这个:
#import <objc/message.h>
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)){
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
}
}
您应该在AppDelegate的didFinishLaunchingWithOptions
方法中添加以下代码:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
这样,在您的应用程序的任何地方,您都可以使用以下代码获取当前方向:
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
使用以下命令测试方向:
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];
}
beginGeneratingDeviceOrientationNotifications
,但现在你需要加上这一行。非常感谢! - borisdiakur[[UIDevice currentDevice] setOrientation:]
的目的是什么?设备不会在旋转时自动设置自己的方向吗? - zakdances这段代码适用于iOS 8或更高的版本。
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
试试这个...对我很有效...
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview]; [window addSubview:view];
这适用于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;
}
注意:我在我的应用程序中实现了这个选项,但可能会被苹果拒绝(注释给Austin,由Sergey K.在2012年10月编辑第6版)。
setTransform
旋转 UIView
并重新应用其自身框架可以得到期望的结果。[YourView setTransform:CGAffineTransformMakeRotation(1.57)];
[YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[YourView setTransform:CGAffineTransformMakeRotation(0)];
[YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];
}
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];
}
}