Vas
Vas

Reputation: 187

Device interface orientation

How can I get the current device interface orientation on app startup, i.e. orientation of main screen containing app icons? For example, iPad is laying screen up (UIDeviceOrientationFaceUp) with landscape interface orientation (UIInterfaceOrientationLandscapeLeft) which I want to get. At app startup all interface functions like

give wrong default value UIInterfaceOrientationPortrait. Which possible ways are exist?

Upvotes: 2

Views: 766

Answers (1)

foundry
foundry

Reputation: 31745

Interface Orientation

You can get good information about orientation before didFinishLaunchingWithOptions is called...

- (BOOL)application:(UIApplication *)application 
         willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

Here you can interrogate the UIScreen and UIApplication:

[UIScreen mainScreen].bounds
[UIApplication sharedApplication].statusBarOrientation

These will give you the correct width, height and interfaceOrientation based on the OS state when the app was launched. (It's best to avoid viewController.interfaceOrientation in any case, as it is deprecated in iOS8.)

In your question you suggest statusBarOrientation is incorrect, but it's working fine for me on iPad mini / 8.3.

Device Orientation

If you are interested in device orientation, you need to start listening for device orientation notifications. You can do this either in your app delegate on in a view controller - either way makes no difference to how soon you will get the information, as the device orientation polling takes time to start up. In addition the first device orientation callback you get can be wrong if you are face up / face down: I think it simply takes a cue from the interface orientation.

This is how you start listening:

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

If you check for deviceOrientation before the first callback, it will be uninitialised so not much use to you. You should stop listening when you are done as this process consumes additional energy.

Here are some logs from a startup sequence, iPad lying face up in landscape orientation:

12:44:39.162 [AppDelegate application:willFinishLaunchingWithOptions:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.165 [AppDelegate application:didFinishLaunchingWithOptions:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.179 [ViewController viewDidLoad] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.180 [ViewController viewWillAppear:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationUnknown / 0

12:44:39.186 [ViewController deviceOrientationDidChange:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationLandscapeRight / 4

12:44:39.204 [ViewController viewDidAppear:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationLandscapeRight / 4

12:44:39.249 [ViewController deviceOrientationDidChange:] 
{1024, 768} UIInterfaceOrientationLandscapeLeft / 0 UIDeviceOrientationFaceUp / 5

The first callback from deviceOrientationDiDChange takes place ~35ms after startup. If the device is lying flat, that first callback is incorrect - and the correct callback takes place ~20ms later. These first deviceOrientation notifications tend to happen between viewWillAppear and viewDidAppear on the first viewController (but these events are not corellated).

For comparision, here is a startup with iPad lying face up in portrait orientation:

12:44:01.741 [AppDelegate application:willFinishLaunchingWithOptions:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.745 [AppDelegate application:didFinishLaunchingWithOptions:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.758 [ViewController viewDidLoad] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.759 [ViewController viewWillAppear:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationUnknown / 0

12:44:01.765 [ViewController deviceOrientationDidChange:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationPortrait / 1

12:44:01.784 [ViewController deviceOrientationDidChange:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationFaceUp / 5

12:44:01.828 [ViewController viewDidAppear:] 
{768, 1024} UIInterfaceOrientationPortrait / 2 UIDeviceOrientationFaceUp / 5

Logging

[UIScreen mainScreen].bounds.size 
[UIApplication sharedApplication].statusBarOrientation
[UIDevice currentDevice].orientation

with some ENUM->NSString lookups

Upvotes: 1

Related Questions