如何在iOS 6中以编程方式更改设备方向

时间:2012-09-29 05:14:29

标签: ios objective-c uiinterfaceorientation

iOS 5 中,我们可以通过编程方式更改设备方向:

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];

但是, iOS 6 setOrientation已被弃用,我如何在 iOS 6 中以编程方式更改设备方向?

15 个答案:

答案 0 :(得分:48)

这是我的“五美分”,在带有ARC的iOS7上测试

[[UIDevice currentDevice] setValue:
                      [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
                            forKey:@"orientation"];

这不会产生“泄漏”警告,因为performSelector会。

UIAlertView - 使用此代码,当你在视图中显示UIAlertView(将会/已经出现)时,你会注意到除了这个视图之外的所有视图都是纵向的(苹果,真的吗?)我无法使用强制视图重新定向但发现如果在打开UIAlertView之前稍微延迟,则视图有时间改变方向。

注意我将从2014年9月12日开始发布我的应用周,如果通过或失败,我会更新帖子。

答案 1 :(得分:20)

这不会回答如何更改设备方向,而是可以帮助您的其他信息。

iOS 6界面界面 - shouldAutorotateToInterfaceOrientation :不工作

方法 shouldAutorotateToInterfaceOrientation :iOS 6不支持。不推荐使用。如果你是新手,只是盯着可可工作,并想知道为什么你的视图控制器搞砸了iOS 6并且在iOS 5中完美,只要知道 shouldAutorotateToInterfaceOrientation :不再受支持了。尽管它可能适用于Xcode 4到4.3,但它不适用于Xcode 4.5。

Apple以更清洁的方式提供了一种新方法来完成这项工作。您可以使用 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;
}

以下是UIViewController关于iOS6中方向的添加方法

  1. UIViewController preferredInterfaceOrientationForPresentation

  2. UIViewController shouldAutorotate

  3. UIViewController supportedInterfaceOrientations

  4. 在U6pplication中添加了关于iOS6中的方向的方法

    1. UIApplication supportedInterfaceOrientationsForWindow:

    2. UIInterfaceOrientationMask

答案 2 :(得分:20)

我发现强制设备更改方向的最简单方法是提供一个新的视图控制器(使用presentViewController:animated:completion:),其中新的视图控制器指定了一个特定的首选方向(通过实现方法{{1 }})。

当按预期显示新的视图控制器时,方向将更改为新视图控制器首选的方向。那么,最简​​单的实现(最佳实践?)是将您在特定方向所需的所有功能嵌入到单独的视图控制器中,并根据需要显示它。系统将负责为您更改方向。

显然这可能不适合所有用例,但幸运的是,同样的技巧适用于强制设备更改现有视图控制器的方向。

诀窍是提供一个具有您需要的特定首选方向的新视图控制器,然后立即隐藏它。这将导致在显示新视图控制器时临时更改方向。最好的部分是,当新的视图控制器被解除时,再次查询原始(呈现)视图控制器的-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation,您可以在此处指定所需的最终方向。

这里要注意的一件重要事情是在原始视图控制器中临时禁用自动旋转(当从新呈现的当时视图控制器返回时),这样当用户将手机旋转到新方向时,它不会触发进一步的自动旋转。

下面的代码应该说明我的观点,我的例子强制旋转到肖像,如果你想要其他方向,只需相应地改变。

假设您有一个名为preferredInterfaceOrientationForPresentation的原始视图控制器和一个名为Original的临时视图控制器

ForcePortrait

答案 3 :(得分:10)

试试这个:

#import <objc/message.h>

if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)){
        if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
        {
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
        }
    }

答案 4 :(得分:5)

你应该放置 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
在您的AppDelegate didFinishLaunchingWithOptions方法中。

然后,在您的应用程序中的任何位置,您都可以通过以下方式获取当前方向:

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

答案 5 :(得分:4)

此代码适用于iOS 8或更高版本

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

答案 6 :(得分:2)

Apple在中以编程方式更改设备方向非常困难(故意让您注意)。

据我所知,完成所要求的唯一方法是模拟设备方向的变化。

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

答案 7 :(得分:2)

试试这个......这对我有用......

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview]; [window addSubview:view];

答案 8 :(得分:2)

@implementation UINavigationController(autorotate)

 -(NSUInteger)supportedInterfaceOrientations
 {
   //make the check for iphone/ipad here

    if(IPHONE)
    {
      return UIInterfaceOrientationMaskPortrait;
    } 
    else
    {
      return UIInterfaceOrientationMaskLandscape;
    }
 }

 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
 {
    return UIInterfaceOrientationPortrait;
 }

 - (BOOL)shouldAutorotate
 {
    return NO;
 }

答案 9 :(得分:2)

如果您想避免使用运行时库,请对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];
    }
}

答案 10 :(得分:2)

这适用于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;
}

注意:我在我的应用程序中实现了这个选项,但可能会被Apple拒绝(奥斯汀在2012年10月对Sergey K.编辑的6评论)。

答案 11 :(得分:1)

if (self.interfaceOrientation != UIInterfaceOrientationLandscapeRight) {
// http://stackoverflow.com/questions/181780/is-there-a-documented-way-to-set-the-iphone-orientation
// http://openradar.appspot.com/radar?id=697
// [[UIDevice currentDevice] setOrientation: UIInterfaceOrientationLandscapeRight]; // Using the following code to get around apple's static analysis...
[[UIDevice currentDevice] performSelector:NSSelectorFromString(@"setOrientation:") withObject:(id)UIInterfaceOrientationLandscapeRight];
}

答案 12 :(得分:0)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
    // Return YES for supported orientations
   return NO;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
   return  interfaceOrientation == UIInterfaceOrientationPortrait
           || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ;
}

答案 13 :(得分:0)

这适用于Xcode 6&amp; 5。

- (BOOL)shouldAutorotate {return YES;}
- (NSUInteger)supportedInterfaceOrientations {return (UIInterfaceOrientationMaskPortrait);}

答案 14 :(得分:0)

有趣的是,其他人在没有像这样设置后如何不会遇到问题:

+ (void)setOrientation:(UIDeviceOrientation)orientation {
    [UIDevice.currentDevice setValue:@(orientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
    [UIDevice.currentDevice setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];
}

我的要求是能够强制定向,然后再次旋转到设备自然定向...有UIDeviceOrientationDidChangeNotification可以让您了解有关巫婆定向的信息以旋转设备,但实际上,如果您不这样做,则部分无效在您更改UIDevice中的方向后,立即将其设置为unknown,还有更多细节可以使它变酷,但仍会保留,因为它不在此简单问题的讨论范围之内。