如果UIInterfaceOrientation格局值是相同的常量,我应该如何确定如何在景观中定向视图?

时间:2013-04-14 05:25:10

标签: ios objective-c ipad uiinterfaceorientation

我想提供一个响应方向更改的视图但由于各种原因无法使用iOS的内置自动旋转。在viewDidLoad中,我使用当前方向来确定视图的初始布局:

_originalOrientation = [UIDevice currentDevice].orientation;

// if we were launched flat or unknown, use the status bar orientation as a guide
if (_originalOrientation == UIDeviceOrientationUnknown ||
    _originalOrientation == UIDeviceOrientationFaceDown ||
    _originalOrientation == UIDeviceOrientationFaceUp) {

        _originalOrientation = UIDeviceOrientationFromInterfaceOrientation([UIApplication sharedApplication].statusBarOrientation);
}

从我的评论中可以看出,我需要处理[UIDevice currentDevice].orientation不是可用方向的情况(即设备是平的或未知的方向)。在这种情况下,我尝试使用statusBarOrientation推断设备的方向(使用UIViewController的{​​{1}}将是另一种获取相同信息的方式):

interfaceOrientation

但是我的逻辑无法准确辨别这两种情况,因为它们被UIDeviceOrientation UIDeviceOrientationFromInterfaceOrientation(UIInterfaceOrientation interface) { // note: because UIInterfaceOrientationLandscapeLeft and UIInterfaceOrientationLandscapeRight have the same value, this conversion can't distinguish them if (interface == UIInterfaceOrientationLandscapeLeft) { return UIDeviceOrientationLandscapeLeft; } else if (interface == UIInterfaceOrientationLandscapeRight) { return UIDeviceOrientationLandscapeRight; } else if (interface == UIInterfaceOrientationPortraitUpsideDown) { return UIDeviceOrientationPortraitUpsideDown; } else { return UIDeviceOrientationPortrait; } } 定义为相同的常量值:

UIApplication.h

我是否可以通过其他方式区分// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa). // This is because rotating the device to the left requires rotating the content to the right. typedef NS_ENUM(NSInteger, UIInterfaceOrientation) { UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft }; UIInterfaceOrientationLandscapeLeft?除了使用状态栏方向之外,还有更好的方法来执行我的“后备”逻辑吗?

6 个答案:

答案 0 :(得分:3)

UIDevice的orientation属性是一个enum,可以区​​分左右横向(它们的值分别为3和4),因此您可以检查该值。

typedef enum {
   UIDeviceOrientationUnknown,
   UIDeviceOrientationPortrait,
   UIDeviceOrientationPortraitUpsideDown,
   UIDeviceOrientationLandscapeLeft,
   UIDeviceOrientationLandscapeRight,
   UIDeviceOrientationFaceUp,
   UIDeviceOrientationFaceDown
} UIDeviceOrientation;

答案 1 :(得分:3)

您写道:

  

然而,我的逻辑无法准确地辨别出两个景观案例   因为它们被定义为UIApplication.h是相同的常量值

我很确定他们不是!接口和设备方向的值交换。见UIApplication.h

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
};

界面方向 UIInterfaceOrientationLandscapeLeft等于设备方向 UIDeviceOrientationLandscapeRight,反之亦然。但是:

  • UIInterfaceOrientationLandscapeLeft != UIInterfaceOrientationLandscapeRight
  • UIDeviceOrientationLandscapeLeft != UIDeviceOrientationLandscapeRight

试试这段代码,我认为这样可以解决问题:

UIDeviceOrientation UIDeviceOrientationFromInterfaceOrientation(UIInterfaceOrientation interface) {
    // interface orientation left is device orientation right
    if (interface == UIInterfaceOrientationLandscapeLeft) {
        return UIDeviceOrientationLandscapeRight;

    // interface orientation right is device orientation left
    } else if (interface == UIInterfaceOrientationLandscapeRight) {
        return UIDeviceOrientationLandscapeLeft;

    } else if (interface == UIInterfaceOrientationPortraitUpsideDown) {
        return UIDeviceOrientationPortraitUpsideDown;

    } else {
        return UIDeviceOrientationPortrait;
    }
}
顺便说一下,您还应考虑为您的函数使用自己的前缀而不是UI,否则可能很容易错误地认为UIDeviceOrientationFromInterfaceOrientation是API函数。

答案 2 :(得分:0)

如果您正在显示相机所看到的内容,我会忽略所有方向,并向用户显示设备在纵向中看到的内容。他们所看到的将永远是“正确的”,并且永远不会意外颠倒。

答案 3 :(得分:0)

您始终可以使用gravity类的CMDeviceMotion属性来确定设备方向。属性返回指向地球中心的标准化向量(也称为真实重力向量)。如果你对角度不感兴趣,你可以只测试符号并为你的目的生成常数。

答案 4 :(得分:0)

这是我在传递中的方式

创建一个名为previousOr的全局变量。然后在您的第一个viewController中使用以下代码来确定状态栏位置。我把它放在viewDidAppear

if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) {
    previousOr = [NSString stringWithFormat:@"L"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
    previousOr = [NSString stringWithFormat:@"L"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
    previousOr = [NSString stringWithFormat:@"P"];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
    previousOr = [NSString stringWithFormat:@"P"];
}

然后在您的后续viewControllers中,您在ViewDidLoad方法中有以下内容,这将检测设备是纵向还是横向,或者设备是否平坦,设备在放平之前所处的位置:

if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
    NSLog(@"landscape");
    [self switchToLandscape];
}
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)) {
    NSLog(@"portrait");
    [self switchToPortrait];
}
else {
    if ([previousOr isEqualToString:@"L"]) {
        [self switchToLandscape];
    }
    else  {
        [self switchToPortrait];
    }
}

然后你还有以下内容来重新绘制视图中的元素

- (void)switchToLandscape {
    previousOr = [NSString stringWithFormat:@"L"];
    //do stuff like replot centers
}

- (void)switchToPortrait {
    previousOr = [NSString stringWithFormat:@"P"];
    //do stuff like replot centers
}

然后您还可以检测方向的变化:

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) {
    [self switchToLandscape];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) {
    [self switchToLandscape];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
    [self switchToPortrait];
}
else if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown) {
    [self switchToPortrait];
}
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

-(BOOL) shouldAutorotate {
    return YES;
}

请注意;为了向后兼容,我输入了shouldAutorotateToInterfaceOrientation和shouldAutoRotate。

答案 5 :(得分:0)

遇到了同样的问题。这就是答案,请始终使用UIIntefaceOrientation来检查当前方向是横向还是纵向。

目标C:

if([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeRight)
 {
         //Go Here for landscape
 }
    else if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown)
 {
        //Go Here for Portrait

 }

SWIFT:

let currentOrient : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
if currentOrient == UIInterfaceOrientation.landscapeLeft || currentOrient == UIInterfaceOrientation.landscapeRight
 {
            //Go Here for landscape
 }
else if currentOrient == UIInterfaceOrientation.portrait || currentOrient == UIInterfaceOrientation.portraitUpsideDown
 {
            //Go Here for Portrait
 }