Get current orientation of iPad?
Asked Answered
I

11

64

In a given event handler (not the "shouldAutorotateToInterfaceOrientation" method) how do I detect the current iPad orientation? I have a text field I have to animate up (when keyboard appears) in the Landscape view, but not in the portrait view and want to know which orientation I'm in to see if the animation is necessary.

Iiette answered 29/4, 2010 at 15:49 Comment(0)
T
133

Orientation information isn't very consistent, and there are several approaches. If in a view controller, you can use the interfaceOrientation property. From other places you can call:

[[UIDevice currentDevice] orientation]

Alternatively, you can request to receive orientation change notifications:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];

Some people also like to check the status bar orientation:

[UIApplication sharedApplication].statusBarOrientation
Tokenism answered 29/4, 2010 at 16:0 Comment(10)
This helped me a lot. I was using [[UIDevice currentDevice] orientation] but when you started the device Face up it was impossible to tell which way the interface was facing. Using [UIApplication sharedApplication].statusBarOrientation has solved this for me. Thanks a lot.Cottonweed
Note that [[UIDevice currentDevice] orientation] will return 0 unless orientation notifications have been enabled.Dim
[[UIDevice currentDevice] orientation] is faulty..It wasted my so much time..Thanks..Tangible
[[UIDevice currentDevice] orientation] may require you to call [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications] in the view controller you are using it in.Erotic
Note: [[UIDevice currentDevice] orientation] gets the device rotation, not the interface rotation! If the user has locked his device's orientation, the device orientation and the interface orientation may be very different. statusBarOrientation returns an interface orientation, which is proper when the user locked his device's orientation.Tishatishri
Don't use [[UIDevice currentDevice] orientation] for this: The value of the property is a constant that indicates the current orientation of the device. This value represents the physical orientation of the device and may be different from the current orientation of your application’s user interface. See “UIDeviceOrientation” for descriptions of the possible values.Remediosremedy
The question is asking for the device orientation, not the current application UI orientation, so it seems appropriate.Tokenism
Why the wrong answer is at the top??? UIDevice orientation is for different thing and returns UIDeviceOrientation which is different enumeration... If you force assign it do UIInterfaceOrientation and stupid compiler does not complain, that's your problem as a developer to understand what's wrong.Rahman
Actually, setOrientation: does work - although it is unofficial API. Objective C is a dynamic language, and that is a good thing.Tokenism
interfaceOrientation property of ViewControllers is deprecatedEaddy
C
35

I think

[[UIDevice currentDevice] orientation];

is not really reliable. Sometimes it works, sometimes not... In my apps, I use

[[UIApplication sharedApplication]statusBarOrientation]; 

and it works great!

Chalco answered 4/7, 2011 at 13:32 Comment(4)
[[UIDevice currentDevice] orientation] is faulty..It wasted my so much time..Thanks..Tangible
"Reliable" is not the problem. The problem is that UIDevice's orientation is not for this purpose. See the documentation: developer.apple.com/library/ios/documentation/uikit/reference/…Remediosremedy
In my code, I need to know to different orientations : the interface one and the device one. The device one is important when you are taking pictures.Brigittebriley
if(UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication]statusBarOrientation])){// landscape}else{//portrait}Misspeak
M
9

One of:

  • Check the interfaceOrientation property of the active view controller.
  • [UIApplication sharedApplication].statusBarOrientation.
  • [UIDevice currentDevice].orientation. (You may need to call -beginGeneratingDeviceOrientationNotifications.)
Meilhac answered 29/4, 2010 at 15:58 Comment(0)
C
8

I found a trick to solve the FaceUp orientation issue!!!

Delay the orientation check till AFTER the app has started running, then set variables, view sizes, etc.!!!

//CODE

- (void)viewDidLoad {

  [super viewDidLoad];

  //DELAY
  [NSTimer scheduledTimerWithTimeInterval:0.5 
                     target:self 
                     selector:@selector(delayedCheck) 
                     userInfo:nil 
                     repeats:NO];

}


-(void)delayedCheck{

  //DETERMINE ORIENTATION
  if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait ){
      FACING = @"PU";
  }
  if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown ){
      FACING = @"PD";
  }
  if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft ){
      FACING = @"LL";
  }
  if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight ){
      FACING = @"LR";
  } 
  //DETERMINE ORIENTATION

  //START
  [self setStuff];
  //START

}


-(void)setStuff{

  if( FACING == @"PU" ){
          //logic for Portrait
  }
  else
  if( FACING == @"PD" ){
          //logic for PortraitUpsideDown
  }
  else{ 
  if( FACING == @"LL"){
          //logic for LandscapeLeft
  }
  else
  if( FACING == @"LR" ){
          //logic for LandscapeRight
  }

}

//CODE

You can addSubviews, position elements, etc. in the 'setStuff' function ... anything that would initially depend on the orientation!!!

:D

-Chris Allinson

Conn answered 3/5, 2011 at 17:31 Comment(3)
Yes, but what if your app has to draw something earlier, because the screen will turn black otherwise?Kip
When an application launches it initially displays the splash screen image. In the applications I make I usually have the appDelegate viewcontroller's .xib file display the same image as the splash screen and then have it fade out. I listen to when the fade out has finished, and then add subviews that have an alpha of 0.0 and then fade them in. It's a nice effect (similar to video games that display the contributing companies before you can play). I keep all of my drawing logic in these added classes so the app has already finished launching and is running when the drawing code is executed.Conn
Asynchronously dispatching to the main queue is sufficient. The event will still fire after the orientation has been handled, but before the screen updates.Remediosremedy
M
3

You can achieve this by two ways:

1- By using the following method:

**Put the following line in the -(void)viewDidLoad Method:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceRotated:) name:UIDeviceOrientationDidChangeNotification object:nil];

then put this method inside your class

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

   UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
    {
        //Do your textField animation here
    }
}

The above method will check the orientation when the device will be rotated

2- The second way is by inserting the following notification inside -(void)viewDidLoad

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

then put the following method inside your class

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

The above method will check the orientation of the status bar of the ipad or iPhone and according to it you make do your animation in the required orientation.

Mulvey answered 13/11, 2012 at 7:36 Comment(0)
S
2

For determining landscape vs portrait, there is a built-in function:

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
BOOL inLandscape = UIDeviceOrientationIsLandscape(orientation);
Sims answered 8/5, 2012 at 22:35 Comment(0)
F
1

[UIApplication sharedApplication].statusBarOrientation returns portrait when it's landscape, and landscape when it's portrait at launch, in iPad

Fichtean answered 12/2, 2013 at 16:15 Comment(0)
W
0

I don't know why, but every time my app starts, the first 4 are right, but subsequently I get the opposite orientation. I use a static variable to count this, then have a BOOL to flip how I manually send this to subviews.

So while I'm not adding a new stand-alone answer, I'm saying use the above and keep this in mind. Note: I'm receiving the status bar orientation, as it's the only thing that gets called when the app starts and is "right enough" to help me move stuff.

The main problem with using this is the views being lazily loaded. Be sure to call the view property of your contained and subviews "Before" you set their positions in response to their orientation. Thank Apple for not crashing when we set variables that don't exist, forcing us to remember they break OO and force us to do it, too... gah, such an elegant system yet so broken! Seriously, I love Native, but it's just not good, encourages poor OO design. Not our fault, just reminding that your resize function might be working, but Apple's Way requires you load the view by use, not by creating and initializing it

Welt answered 9/3, 2012 at 17:25 Comment(0)
U
0

In your view controller, get the read-only value of self.interfaceOrientation (the current orientation of the interface).

Urnfield answered 16/11, 2012 at 14:14 Comment(0)
R
0

I've tried many of the above methods, but nothing seemed to work 100% for me.

My solution was to make an iVar called orientation of type UIInterfaceOrientation in the Root View Controller.

- (void)viewDidLoad {

    [super viewDidLoad];
    orientation = self.interfaceOrientation; // this is accurate in iOS 6 at this point but not iOS 5; iOS 5 always returns portrait on app launch through viewDidLoad and viewWillAppear no matter which technique you use.
}


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

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

    orientation =  toInterfaceOrientation;

}

Then, any place where you need to check the orientation you can do something like this:

 if(UIInterfaceOrientationIsPortrait(orientation)){
    // portrait
  }else{
   // landscape
  }

There may still be a better way, but this seems to work 98% of the time (iOS5 notwithstanding) and isn't too hard. Note that iOS5 always launches iPad in portrait view, then sends a device the willRotateTo- and didRotateFromInterfaceOrientation: messages, so the value will still be inaccurate briefly.

Rebekahrebekkah answered 5/4, 2013 at 22:44 Comment(0)
H
-1

[UIDevice currentDevice].orientation works great.

BUT!!! ... the trick is to add it to - (void)viewWillAppear:(BOOL)animated

exp:

(void)viewWillAppear:(BOOL)animated{
   ...
   BOOL isLandscape = UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
   ...
}

If you call it at - (void)viewDidLoad, it does not work reliable, especially if you use multiple threads (main UI thread, background thread to access massive external data, ...).


Comments: 1) Even if your app sets default orientation portrait, user can lock it at landscape. Thus setting the default is not really a solution to work around it. 2) There are other tasks like hiding the navigation bar, to be placed at viewWillAppear to make it work and at the same time prevent flickering. Same applies to other views like UITableView willDisplayCell -> use it to set cell.selected and cell.accessoryType.

Hugo answered 26/4, 2012 at 20:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.