Is anyone know a way to detect the orientation of the iPad programmatically when launch a app.
I'm using following mechanism.
- (void) detectDeviceInitialOrientation
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
MyAppDelegate *appDelegate=(MyAppDelegate*)[[UIApplication sharedApplication] delegate];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (UIDeviceOrientationIsPortrait(orientation)) {
appDelegate.orintation = PORTRAIT;
}
else if (UIDeviceOrientationIsLandscape(orientation)) {
appDelegate.orintation = LANDSCAPE;
}
}
But it fails to detect the device's orientation when it lay parallel to the floor. So, I'm looking another solution. Please help......
Have a look at the UIDeviceOrientation enum in the docs.
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;
Notice that this defines UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown. Unfortunately, there is no built in check for whether the device is in one of these orientations like there is for portrait or landscape. However, you can do the checking your self with a simple if statement. Something like this:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationFaceUp || orientation == UIDeviceOrientationFaceDown) {
// device is flat on the ground
}
Related
I do some custom layout including an animation in willAnimateRotationToInterfaceOrientation:duration:
The problem I have is that if the device changes from landscapeLeft to landscapeRight the interface should rotate but the layout code, especially the animation should not be run. How can I detect that it is changing from one landscape to another? self.interfaceOrientation as well as [[UIApplication sharedApplication] statusBarOrientation] don't return valid results, they seem to think the device is already rotated. As a result the following does not work.
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation) && UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) {...}
You can check the device orientation and then set a flag as to whether you are in left orientation or right orientation. Then when your device switches you can catch it and handle it however you want.
To determine orientation use:
if([UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft)
{
//set Flag for left
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
{
//set Flag for right
}
You can also catch a notification when the device is rotating using:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(detectOrientation) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
And then write a method for detectOrientation like so:
-(void) detectOrientation
{
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft)
{
//Set up left
} else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
{
//Set up Right
} else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
{
//It's portrait time!
}
}
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation ]== UIDeviceOrientationLandscapeRight)
{
NSLog(#"Lanscapse");
}
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown )
{
NSLog(#"UIDeviceOrientationPortrait");
}
}
It seems that the only solution is to cache the last orientation change. By the time willAnimateRotationToInterfaceOrientation: is called the device and interface orientations have already been updated. The solution is to record the destination orientation at the end of each change so that this value can be queried when the orientation is set to change again. This is not as elegant as I was hoping (yet another property on my view controller) but seems to be the only way as far as I can tell.
I need to get device orientation from a ViewController. I cannot base on:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
because it sometimes returns orientation unknown (for example when the device lays on the table).
I just need to know in what orientation is my current UIView displayed (is it landscape left or landscape right). I don't need to have this value updated when orientation changes, I just want to know it, when I ask for it. Just some reference view.orientation ;). Is there something that would help me? I've read UIView documentation, found some reference to UIWindow, but nothing that could help me.
You can also get the device orientation from UIApplication, have you tried using
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
UIViewController has a property
UIInterfaceOrientation interfaceOrientation;
So in your UIViewController, you can access the current orientation of the device at any time via
UIInterfaceOrientation myCurrentOrientation = self.interfaceOrientation;
Swift Version
let currentOrientation:UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
if currentOrientation.isPortrait {
print("PORTRAIT")
} else if currentOrientation.isLandscape {
print("LANDSCAPE")
}
Following is the sample code to do the same. There is a variable named deviceOrientation, and it will answer the current orientation of device, whenever being asked.
UIDeviceOrientation deviceOrientation;
- (void)viewWillAppear:(BOOL)animated
{
deviceOrientation = (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation];
[self willAnimateRotationToInterfaceOrientation:deviceOrientation duration:0.5];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
deviceOrientation = (UIDeviceOrientation)interfaceOrientation;
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
NSLog(#"Landscape");
}
else
{
NSLog(#"Portrait");
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return TRUE;
}
I have a UIWebView that I would like to load different URLs depending on whether its portrait or landscape. How can I figure out what my current orientation is inside viewWillAppear?
Use UIApplication's statusBarOrientation property. You may run into problems if you use the device orientation if it is UIDeviceOrientationFaceUp or UIDeviceOrientationFaceDown.
Example
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsLandscape(orientation))
{
// Do something when in landscape
}
else
{
// Do something when in portrait
}
UIDeviceOrientation getCurrentOrientation() {
UIDevice *device = [UIDevice currentDevice];
[device beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation currentOrientation = device.orientation;
[device endGeneratingDeviceOrientationNotifications];
return currentOrientation;
}
It's up to you to convert the UIDeviceOrientation to UIInterfaceOrientation.
When the app loads, it does not know its current orientation-
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
NSLog(#"portrait");// only works after a rotation, not on loading app
}
Once you rotate the device, you get correct orientation, but when the app is loaded, without changing the orientation, it seems that using [[UIDevice currentDevice] orientation] doesn't know the current orientation.
So you need to do 2 things -
Try setting the application's accepted device orientations in the plist file
In your UIViewControllers, you will need to override the shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) method to return YES when the app should rotate:
If the is sequencing of relevant calls mean that you can't rely on interfaceOrientation having the correct value at viewWillAppear then — assuming the parent view controller rotates — the safest thing is probably self.parentViewController.interfaceOrientation. Failing that you could try making a first assumption from [[UIDevice currentDevice] orientation], which may not always be 100% on the money (e.g. if the device is lying flat on a table when your app is launched) but is likely to give you a better guess than always assuming portrait.
I have the following code to fill a view according to the orientation. This always returns landscape.
- (void)setData:(BCPlaylist *)list {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown){
NSLog(#"portrait");
[self setPlaylist:list];
[self renderPlaylist];
[activity stopAnimating];
}else{
NSLog(#"landscape");
[self setPlaylist:list];
[self renderPlaylistOne];
[activity stopAnimating];
}
}
I change views correctly in - (void)animateRotation:(UIInterfaceOrientation)interfaceOrientation
duration:(NSTimeInterval)duration {
But that doesn't work when already in landscape or portrait when changing a playlist.
Instead of using [[UIDevice currentDevice] orientation] for checking orientation use statusbar orientation to get the exact orientation.
UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
To avoid a warning, use :
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
You'd always get landscape, because that's your default (from your if statement). If you walk through the debugger with a breakpoint there, you'll see that the orientation reported is that of Unknown.
In fact, your code is fine, but this is a limitation of the simulator. If you take the same code, using Device orientation and not Interface orientation, you'll get actual values if you use it on the physical device, which can be driven by the if-statement you have.
a noob question here.
i detect the orientation with:
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
all is fine and dandy and I reposition my text fields and labels according to the reported orientation with
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown)
and else{} for everything else
the problem that i only recently discovered is when the UIDevice reports UIDeviceOrientationFaceUp or UIDeviceOrientationFaceDown. how do I deal with this situation ? how do I know whether UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown is happening in Portrait or Landscape ? I know that the device is facing up or down, but I don't know if I should reposition everything to Portrait or Landscape.
thank you!
Apple recommends against using device orientation for view layout. Instead, each view controller has an interfaceOrientation property, and UIApplication has a statusBarOrientation property, both of which will return the current interface orientation, which is suitable for view layout.
To monitor for changes, there are UIViewController methods like willRotateToInterfaceOrientation:duration: that will be called and notifications such as UIApplicationWillChangeStatusBarOrientationNotification that will be posted when an interface orientation change occurs.
A bit late, hopefully it would help some one.
For iOS 6.0 and later:
1) Set this code during your View Setup to receive rotation notification:
// Set Listener to receive orientation notifications from the device
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(detectOrientation)
name:UIDeviceOrientationDidChangeNotification
object:nil];
2) Set this code to catch the Notification after rotation:
-(void)detectOrientation{
switch ([[UIDevice currentDevice] orientation]) {
case UIDeviceOrientationFaceDown:{
NSLog(#"UIDeviceOrientationFaceDown");
break;
}
case UIDeviceOrientationFaceUp:{
NSLog(#"UIDeviceOrientationFaceUp");
break;
}
case UIDeviceOrientationLandscapeLeft:{
NSLog(#"UIDeviceOrientationLandscapeLeft");
break;
}
case UIDeviceOrientationLandscapeRight:{
NSLog(#"UIDeviceOrientationLandscapeRight");
break;
}
case UIDeviceOrientationPortrait:{
NSLog(#"UIDeviceOrientationPortrait");
break;
}
case UIDeviceOrientationPortraitUpsideDown:{
NSLog(#"UIDeviceOrientationPortraitUpsideDown");
break;
}
case UIDeviceOrientationUnknown:{
NSLog(#"UIDeviceOrientationUnknown");
break;
}
default:{
break;
}
}
}
I have the same problems with
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
This method generate notifications for 7 possible device positional states:
UIDeviceOrientationPortrait
UIDeviceOrientationPortraitUpsideDown
UIDeviceOrientationLandscapeLeft
UIDeviceOrientationLandscapeRight
UIDeviceOrientationFaceUp
UIDeviceOrientationFaceDown
UIDeviceOrientationUnknown
But I only need the first 4, well this is my approach to solve this problem (with code included):
How to handle UIDeviceOrientation for manage views layouts