如何在iOS 7/8中的应用启动时获得初始设备方向?

时间:2014-11-13 18:56:11

标签: ios objective-c rotation orientation

我正在实施类似于Apple相机应用的照片/视频选择界面。我需要进行手动界面旋转,因为我不希望预览视图旋转,但我确实想要相应地旋转控件。因此,我的视图控制器(应用程序的根视图控制器)中有以下代码:

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

要检测方向更改,我在viewDidLoad

中注册了VC以获取相应的通知
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(deviceOrientationDidChange)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:[UIDevice currentDevice]];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

当我以除了人像之外的方向启动应用程序时,这可以按预期的除外。我的回调被调用;但是,当前设备方向始终为UIDeviceOrientationPortrait,即使我在启动应用程序时将设备侧向握住也是如此。状态栏方向也是如此。

如何在应用启动后立即找出设备方向?我知道这是可能的,因为Apple正在使用他们的相机应用程序。问题是,是否有任何官方方式,或者他们是否使用了一些神奇的内部API?

更新

安娜的答案证明是正确的,但你也应该阅读评论。 TL; DR :当应用未针对它们进行优化时,效果会发生在iPhone 6(Plus)上。

1 个答案:

答案 0 :(得分:1)

首先,您不希望查看UIDevice方向(请参阅this post)。

我认为在UI完成配置之前,你会得到一个虚假的结果。换句话说,它报告肖像,因为它在启动过程中的那个时候还没准备好。为什么要发送通知?不确定;但是,你绝对不想将它们用于你的任务。

我不太明白你使用的初始方向是什么,但我有另一种方法可以解决你的问题:你可以通过反转来保持视图静态。当视图控制器收到旋转消息(即viewDidRotate,iOS 8之前版本)时,您可以更改静态视图上的变换,使其沿与旋转方向相反的方向旋转。

也许有一些聪明的方法可以用autolayout来做,但我还没想出来...... :-p

编辑:

一些代码......

YMMV - 这个有效,但我有一段时间没碰过它!您可能需要稍微玩一下......与我在评论中所说的相反,看起来我动画旋转。但是,它真的不动!我认为反旋转动画会被整个显示器的系统旋转取消。或者其他东西。

simViewControllerContainer是我阻止旋转的视图。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Set simView container's orientation if the device started in landscape
    if ( self.interfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
        simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
        simViewControllerContainer.transform = CGAffineTransformMakeRotation(-M_PI/2);
    }
    else if ( self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
        simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
        simViewControllerContainer.transform = CGAffineTransformMakeRotation(M_PI/2);
    }
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    BOOL doubleRotation =
    (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) && UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) ||
    (UIInterfaceOrientationIsLandscape(self.interfaceOrientation) && UIInterfaceOrientationIsLandscape(toInterfaceOrientation));

    if ( toInterfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
        [UIView animateWithDuration:duration animations:^{
            if ( !doubleRotation ) {
                // For a double-rotation, we don't want to change the center -- it's the same:
                // a double-rotation is landscape to landscape or portrait to portrait -- same center.
                simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
            }
            simViewControllerContainer.transform = CGAffineTransformMakeRotation(-M_PI/2);
        }];
    }
    else if ( toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
        [UIView animateWithDuration:duration animations:^{
            if ( !doubleRotation ) {
                simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
            }
            simViewControllerContainer.transform = CGAffineTransformMakeRotation(M_PI/2);
        }];

    }
    else if ( toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ) {
        [UIView animateWithDuration:duration animations:^{
            if ( !doubleRotation ) {
                simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
            }
            simViewControllerContainer.transform = CGAffineTransformIdentity;
        }];

    }
    else if ( [UIDevice currentDevice].orientation == UIDeviceOrientationPortrait ) {
        [UIView animateWithDuration:duration animations:^{
            if ( !doubleRotation ) {
                simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
            }
            simViewControllerContainer.transform = CGAffineTransformIdentity;
        }];
    }
}