iOS:加载时的设备方向

时间:2011-05-04 18:16:53

标签: iphone ios uiinterfaceorientation uidevice

似乎当我的应用加载时,它不知道它的当前方向:

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
    NSLog(@"portrait");// only works after a rotation, not on loading app
}

一旦我旋转设备,我得到了正确的方向,但是当我加载应用程序而不改变方向时,似乎使用[[UIDevice currentDevice] orientation]并不知道当前的方向。

我第一次加载应用时是否还有另一种检查方法?

16 个答案:

答案 0 :(得分:65)

编辑:我误读了您的问题。这将允许您以某些方向启动应用程序。刚刚意识到你正试图弄清楚发布的方向。

有一种方法可以检查UIApplication上的状态栏方向:

[[UIApplication sharedApplication] statusBarOrientation];

原始答案

尝试在plist文件中设置应用程序接受的设备方向:

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

这表示您的应用程序支持纵向(底部的主页按钮),左侧横向和右侧横向。

然后,在你的UIViewControllers中,当应用程序应该旋转时,你需要覆盖shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)方法返回YES:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

     return interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

如果设备处于您支持的方向之一,这将告诉UIViewController自动旋转。如果你想支持颠倒的方向(顶部带有主页按钮的肖像),那么将它添加到你的plist中,然后从这个方法中返回YES。

让我们知道它是如何运作的。

答案 1 :(得分:11)

我认为这会奏效:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;

根据UIDevice参考:
报价:
“除非通过调用beginGeneratingDeviceOrientationNotifications启用了方向通知,否则此属性的值始终返回0” 我最初认为这个属性在任何时候都包含当前的方向,但显然不是这样。我想在通常访问orientation属性的其他情况下,我们会在幕后处理启用通知,因此不需要在app delegate中手动完成此操作

答案 2 :(得分:2)

有人提到的一件事就是你在UIDeviceOrientation变量中存储了UIInterfaceOrientation个类型。它们是不同的,不应该被视为平等。请注意UIDeviceOrientationLeft等于UIInterfaceOrientationRight(因为与设备相比,界面以相反的方式旋转)。

答案 3 :(得分:2)

您可以通过在

中插入以下通知来完成此操作
-(void)viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

然后将以下方法放入您的班级

-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
    {
         //Do your textField animation here
    }
}

上述方法将检查ipad或iPhone状态栏的方向,并根据它以所需的方向制作动画。

答案 4 :(得分:2)

在加载时,设备方向可以是.Unknown.FaceUp。要弄清楚它是纵向还是横向,我使用statusBarOrientation作为后备,如下所示:

    var portraitOrientation = UIDevice.currentDevice().orientation == .Portrait

    if UIDevice.currentDevice().orientation == .Unknown || UIDevice.currentDevice().orientation == .FaceUp {
        portraitOrientation = UIApplication.sharedApplication().statusBarOrientation == .Portrait
    }

这样我可以确保portraitOrientation总是告诉我设备是否处于纵向模式,如果不是,它将处于横向状态。即使是第一次加载应用程序。

答案 5 :(得分:1)

为了从状态栏获取方向,在plist文件中启用所有方向也很重要。

答案 6 :(得分:1)

Swift 3 基于@Marjin的代码。

var portraitOrientation = UIDevice.current.orientation == .portrait

if UIDevice.current.orientation == .unknown || UIDevice.current.orientation == .faceUp {
     portraitOrientation = UIApplication.shared.statusBarOrientation == .portrait
}

if(portraitOrientation)
{
     // Portrait
}
else
{

}

答案 7 :(得分:0)

尝试使用加速计获取其读数,UIAccelerometer,获取sharedAccelerometer,设置其代表,获取读数,从那里找出方向。

答案 8 :(得分:0)

尝试了所有并且没有好结果。所以,我在ipad上所做的就是将所有工作留给splitViewController方法以使barButton无效:

肖像:

- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc { NSlog(@"portrait");}

对于风景:

- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem{ NSlog(@"landscape");}

这总是适用于负载。

答案 9 :(得分:0)

问题是[UIDevice currentDevice]orientation]有时会错误地报告设备的方向。

而是使用[[UIApplication sharedApplication]statusBarOrientation] UIInterfaceOrientation,因此要检查它是否需要使用UIInterfaceOrientationIsLandscape(orientation)

希望这会有所帮助。

答案 10 :(得分:0)

我仍然使用iphone 4的这个工作代码片段:

-(void)deviceOrientationDidChange:(NSNotification *)notification{

//Obtaining the current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];    

int value = 0;

if(orientation == UIDeviceOrientationPortrait)
{
    value = 0;

}else if(orientation == UIDeviceOrientationLandscapeLeft)
{
    value = 90;

}else if(orientation == UIDeviceOrientationLandscapeRight)
{

    value = -90;

}

CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(value));
[photoImageView setTransform:cgCTM];

}

答案 11 :(得分:0)

这是真正的答案。当应用程序启动时,它的方向是未知的。它使用shouldAutorotateToInterfaceOrientation和supportedInterfaceOrientations来决定选择哪个方向。

观看我在iPhone 5.0模拟器中启动示例应用程序并使用下面的代码旋转它以及“支持的界面方向”以及所有4种可能的方向:

20:44:08.218 RotationTestApp Supported orientation: Portrait
20:44:08.222 RotationTestApp Supported orientation: Portrait (upside-down)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the right)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the left)
20:44:08.226 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.237 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.239 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.240 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:09.817 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:09.833 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:11.030 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:11.040 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:12.599 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:12.609 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:13.301 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)

我已经看过很多代码片段,但它们都不能正常工作(iPad和iPhone,iOS 5.0 +)。

而不是尝试使用try-this-try-that,将以下内容放在root vc中:

#define ToNSString_BEGIN(T) \
NSString* T##ToNSString(T valueParameter) { \
switch (valueParameter) {

#define ToNSString_VALUE(value) \
case value: return @#value

#define ToNSString_END(T) \
} \
return @"(unknown)"; \
}

// NSString* UIInterfaceOrientationToNSString(UIInterfaceOrientation);
ToNSString_BEGIN(UIInterfaceOrientation);
ToNSString_VALUE(UIInterfaceOrientationPortrait);           // 1
ToNSString_VALUE(UIInterfaceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIInterfaceOrientationLandscapeLeft);      // 3
ToNSString_VALUE(UIInterfaceOrientationLandscapeRight);     // 4
ToNSString_END  (UIInterfaceOrientation);

// NSString* UIDeviceOrientationToNSString(UIDeviceOrientation);
ToNSString_BEGIN(UIDeviceOrientation);
ToNSString_VALUE(UIDeviceOrientationUnknown);               // 0
ToNSString_VALUE(UIDeviceOrientationPortrait);              // 1
ToNSString_VALUE(UIDeviceOrientationPortraitUpsideDown);    // 2
ToNSString_VALUE(UIDeviceOrientationLandscapeLeft);         // 3
ToNSString_VALUE(UIDeviceOrientationLandscapeRight);        // 4
ToNSString_VALUE(UIDeviceOrientationFaceUp);                // 5
ToNSString_VALUE(UIDeviceOrientationFaceDown);              // 6
ToNSString_END  (UIDeviceOrientation);



// Change this custom method to alter auto-rotation behavior on all supported iOS versions and platforms.
- (BOOL)allowAutoRotate:(UIInterfaceOrientation)interfaceOrientation
{
    NSUInteger interfaceOrientationAsMask = (1<<interfaceOrientation);
    return interfaceOrientationAsMask & [self supportedInterfaceOrientations];
}

// Reads from the project's-Info.plist
- (NSUInteger)supportedInterfaceOrientations
{
    static NSUInteger orientationsResult;

    if (!orientationsResult) {
        NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];

        for (id orientationString in supportedOrientations) {
            if ([orientationString isEqualToString:@"UIInterfaceOrientationPortrait"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortrait;
                NSLog(@"Supported orientation: Portrait");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortraitUpsideDown;
                NSLog(@"Supported orientation: Portrait (upside-down)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeRight"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeRight;
                NSLog(@"Supported orientation: Landscape (home button on the left)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeLeft;
                NSLog(@"Supported orientation: Landscape (home button on the right)");
            } else {
                NSLog(@"Unrecognized orientation '%@' in mainBundle plist, key UISupportedInterfaceOrientations", orientationString);
            }
        }
    }
   return orientationsResult;
}

// iOS 6+ (not yet used in 6.0.1)
- (BOOL)shouldAutorotate
{
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
    BOOL result = [self allowAutoRotate:interfaceOrientationFromDevice];
    NSString *currentDeviceOrientation = UIDeviceOrientationToNSString(interfaceOrientationFromDevice);
    NSLog(@"shouldAutorotate: %s (current orientation %@)", result ? "YES" : "NO", currentDeviceOrientation);
    return result;
}

// iOS 2.0 - 5.1 (iOS 6+ deprecated, 6.0.1 still works)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    NSString* orientationString;
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;

    if ((int)interfaceOrientation != (int)interfaceOrientationFromDevice) {
        orientationString = [NSString stringWithFormat:@"current device orientation: %@, interface orientation wants: %@",
                             UIDeviceOrientationToNSString(interfaceOrientationFromDevice),
                             UIInterfaceOrientationToNSString(interfaceOrientation)
                             ];
    } else {
        orientationString = [NSString stringWithFormat:@"device orientation: %@", UIDeviceOrientationToNSString(interfaceOrientationFromDevice)
                             ];
    }

    BOOL result = [self allowAutoRotate:interfaceOrientation];
    NSLog(@"shouldAutorotateToInterfaceOrientation: %s (%@)",
          result ? "YES" : "NO",
          orientationString);
    return result;
}

仍然存在不使用当前方向的segue动画的唠叨问题。我的猜测是,为每个VC创建子类并在pop上通知push / notify委托的方法是可行的。

同样重要的是:

shouldAutorotateToInterfaceOrientation doesn't work

tabBarController and navigationControllers in landscape mode, episode II

答案 12 :(得分:0)

试试这个。它为我工作。粗糙的那个时候,didfinishedlaunch方法没有检测到设备方向。它默认为肖像。所以。我用来检查统计栏方向。我测试这段代码。把它放在appdeleget中的didfinishedlaunch方法中。

UIInterfaceOrientation orientation = [UIApplication sharedApplication] .statusBarOrientation;

if(orientation == 0) {//Default orientation
    //UI is in Default (Portrait) -- this is really a just a failsafe.

    NSLog("for portrait");


}else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{

    NSLog("portrait");
}else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{

    NSLog("Landscap");
}

答案 13 :(得分:0)

试试这个 [[UIApplication sharedApplication] statusBarOrientation];

或在app delegate

中实现此功能
(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}

它有效

答案 14 :(得分:0)

对于那些寻找Swift 3或4的答案的人。只需在viewDidLoad()块中添加该代码。

`let orientation = UIApplication.shared.statusBarOrientation
 if orientation == .portrait {
        // portrait   
 } else if orientation == .landscapeRight || orientation == 
.landscapeLeft{
         // landscape     
 }`

答案 15 :(得分:-1)

上述每个人都发布了非常有效的答案:但作为更新:Apple的观点:您应该使用UIStatusBar方向来读取设备的当前方向:

检查设备当前方向的一种方法是在viewDidLoad方法中使用int值:

    int orientationType = [[UIDevice currentDevice] orientation];

考虑以下内容。 。 。   - 1 =肖像(正确向上)   - 2 =肖像颠倒   - 3 =风景(右)   - 4 =风景(左)

然后你可以使用IF语句在检测到方向后调用方法,依此类推:

希望这对某人有点帮助