[ACCEPTED]-How Do I detect the orientation of the device on iOS?-uidevice
Really old thread, but no real solution.
I 3 Had the same problem, but found out that 2 getting The UIDeviceOrientation isn't always 1 consistent, so instead use this:
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == 0) //Default orientation
//UI is in Default (Portrait) -- this is really a just a failsafe.
else if(orientation == UIInterfaceOrientationPortrait)
//Do something if the orientation is in Portrait
else if(orientation == UIInterfaceOrientationLandscapeLeft)
// Do something if Left
else if(orientation == UIInterfaceOrientationLandscapeRight)
//Do something if right
if UIViewController:
if (UIDeviceOrientationIsLandscape(self.interfaceOrientation))
{
//
}
if UIView:
if (UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
{
//
}
UIDevice.h:
#define UIDeviceOrientationIsPortrait(orientation) ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown)
#define UIDeviceOrientationIsLandscape(orientation) ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight)
Updated:
add 2 this code to xxx-Prefix.pch then you can 1 use it anywhere:
// check device orientation
#define dDeviceOrientation [[UIDevice currentDevice] orientation]
#define isPortrait UIDeviceOrientationIsPortrait(dDeviceOrientation)
#define isLandscape UIDeviceOrientationIsLandscape(dDeviceOrientation)
#define isFaceUp dDeviceOrientation == UIDeviceOrientationFaceUp ? YES : NO
#define isFaceDown dDeviceOrientation == UIDeviceOrientationFaceDown ? YES : NO
usage:
if (isLandscape) { NSLog(@"Landscape"); }
For what You looking for first you have 5 to Get Notification if Orientation Changed! You 4 Can set This Thing in viewDidLoad like
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(OrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
and 3 whenever Orientation of your Device changed 2 OrientationDidChange Called where You can do whatever You Want 1 as Per Orientation
-(void)OrientationDidChange:(NSNotification*)notification
{
UIDeviceOrientation Orientation=[[UIDevice currentDevice]orientation];
if(Orientation==UIDeviceOrientationLandscapeLeft || Orientation==UIDeviceOrientationLandscapeRight)
{
}
else if(Orientation==UIDeviceOrientationPortrait)
{
}
}
If you want to get device orientation directly from accelerometer 2 use [[UIDevice currentDevice] orientation]
. But if you need current orientation 1 of your application(interface orientation) use [[UIApplication sharedApplication] statusBarOrientation]
.
UIViewController
has an interfaceOrientation
property that you can access to 5 find out the current orientation of a view 4 controller.
As for your example, that should 3 work. When you say it isn't working, what 2 do you mean? What results does it give you 1 versus what you expected?
In Swift 3.0
to get device orientation.
/* return current device orientation.
This will return UIDeviceOrientationUnknown unless device orientation notifications are being generated.
*/
UIDevice.current.orientation
to get device orientation from your app
UIApplication.shared.statusBarOrientation
0
Wasn't satisfied by "UIDeviceOrientation" because when a UIViewcontroller 10 orientation is fixed to a specific orientation 9 you don't get a pertinent information with 8 the device orientation, so the right thing 7 to do is using "UIInterfaceOrientation".
You can get the orientation 6 from the UIViewController with a "self.interfaceOrientation", but when 5 you are factorizing our code, you might 4 need to do this kind of test outside a view 3 controller, (custom view, a category…), so 2 you still can access the information anywhere 1 outside the controller by using the rootviewController:
if (UIInterfaceOrientationIsLandscape(view.window.rootViewController.interfaceOrientation)) {
}
There's a way to achieve this whether the 2 orientation lock is enabled or not by using data from CoreMotion. This is 1 the code:
#import <CoreMotion/CoreMotion.h>
CMMotionManager *cm=[[CMMotionManager alloc] init];
cm.deviceMotionUpdateInterval=0.2f;
[cm startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMDeviceMotion *data, NSError *error) {
if(fabs(data.gravity.x)>fabs(data.gravity.y)){
NSLog(@"LANSCAPE");
if(data.gravity.x>=0){
NSLog(@"LEFT");
}
else{
NSLog(@"RIGHT");
}
}
else{
NSLog(@"PORTRAIT");
if(data.gravity.y>=0){
NSLog(@"DOWN");
}
else{
NSLog(@"UP");
}
}
}];
Have you unlocked the hardware lock for 2 device orientation? There is one at the 1 edge of my iPad 1.
Here is some Swift variables to make detection 1 easier:
let LANDSCAPE_RIGHT: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight
let LANDSCAPE_LEFT: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft
let LANDSCAPE: Bool = LANDSCAPE_LEFT || LANDSCAPE_RIGHT
let PORTRAIT_NORMAL: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait
let PORTRAIT_REVERSE: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.PortraitUpsideDown
let PORTRAIT: Bool = PORTRAIT_REVERSE || PORTRAIT_NORMAL
My current way of doing this:
+ (BOOL)isPortrait {
let window = UIApplication.sharedApplication.delegate.window;
if(window.rootViewController) {
let orientation =
window.rootViewController.interfaceOrientation;
return UIInterfaceOrientationIsPortrait(orientation);
} else {
let orientation =
UIApplication.sharedApplication.statusBarOrientation;
return UIInterfaceOrientationIsPortrait(orientation);
}
}
If there is 2 for some reason no rootViewController yet 1 fail safe to statusBarOrientation...
And the best reliable way in swift :
public extension UIScreen {
public class var isPortrait: Bool {
UIApplication.shared.delegate?.window??.rootViewController?.interfaceOrientation.isPortrait ??
UIApplication.shared.statusBarOrientation.isPortrait
}
public class var isLandscape: Bool { !isPortrait }
}
0
This is my solution with Combine, which 4 is quite easy to use with SwiftUI or regular 3 Swift Object. A singleton object (static 2 instance) is better than the "environment" for 1 this kind of truly global object.
// Singleton object to keep the interface orientation (and any other global state)
class SceneContext: ObservableObject {
@Published var interfaceOrientation = UIInterfaceOrientation.portrait
static let shared = SceneContext()
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
func windowScene(_ windowScene: UIWindowScene, didUpdate previousCoordinateSpace: UICoordinateSpace, interfaceOrientation previousInterfaceOrientation: UIInterfaceOrientation, traitCollection previousTraitCollection: UITraitCollection) {
SceneContext.shared.interfaceOrientation = windowScene.interfaceOrientation
}
}
// if you want to execute some code whenever the orientation changes in SwiftUI
someView {
....
}
.onReceive(SceneContext.shared.$interfaceOrientation) { (orientation) in
// do something with the new orientation
}
// if you want to execute some code whenever the orientation changes in a regular Swift object
let pub = SceneContext.shared.$interfaceOrientation.sink(receiveValue: { (orientation) in
// do something with the new orientation
...
})
Use This Function.
func deviceOrientation() -> String! {
let device = UIDevice.current
if device.isGeneratingDeviceOrientationNotifications {
device.beginGeneratingDeviceOrientationNotifications()
var deviceOrientation: String
let deviceOrientationRaw = device.orientation.rawValue
switch deviceOrientationRaw {
case 1:
deviceOrientation = "Portrait"
case 2:
deviceOrientation = "Upside Down"
case 3:
deviceOrientation = "Landscape Right"
case 4:
deviceOrientation = "Landscape Left"
case 5:
deviceOrientation = "Camera Facing Down"
case 6:
deviceOrientation = "Camera Facing Up"
default:
deviceOrientation = "Unknown"
}
return deviceOrientation
} else {
return nil
}
}
0
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.