Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the proper way to detect interface orientation at launch?

[Question updated]

So here is the problem, I finally narrowed it down to this. If you create a new UIViewController in all methods

- (id)init;
- (void)loadView;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewDidLoad;
(...)

The standard interfaceOrientation is Portrait and if landscape mode is detected it will quickly rotate to that orientation. Which can then be detected using the:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;

The problem is that on the iPad, it's quiet difficult to prepare your interface for the current interface orientation within the loadView (or one of the others) as it will only return Portrait. This will cause for a few problems:

1) I want my content to reload in portait mode, but NOT in landscape mode. Normally I would place an if statement in the loadView. If in portrait mode, reload content. But in this case it will always return portrait and thus always loads content.

2) I want to use 'presentPopoverFromRect:inView:permittedArrowDirections:animated:'-method when in portrait mode so it will present the popover menu automaticly when the application starts. This will crash the application when launched in portrait mode. Reason: 'Popovers cannot be presented from a view which does not have a window.'.

The only safe assumption is within 'didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation', but this method will not be fired if it launches in portrait mode.

//----

Update (15.37)

'UIApplicationWillChangeStatusBarOrientationNotification'

Will only be posted when the user swaps from portrait to landscape (or vica versa). If interface was the problem then this can easily be solved with observing for that notification and

if (UIDeviceOrientationIsPortrait(interfaceOrientation)) {
    // layout subviews for portrait mode
} else {
    // layout subviews for landscape mode
}

But the problem is that I want to know in which mode it is at launch to determine rather or not I should reload the content, I can't reload the content and when it swaps to landscape cancel it.

like image 380
Mark Avatar asked Nov 21 '10 18:11

Mark


People also ask

How to detect the orientation of the screen/ device using JavaScript?

Below are the most useful ways to get/ detect the orientation of the screen/ device using JavaScript. 1. How to detect screen orientation using window object if (window.innerHeight > window.innerWidth) { alert("You are in portrait mode"); } if (window.innerHeight < window.innerWidth) { alert("You are in landscape mode"); } 2.

Is there a way to detect when a user changes orientation?

Since screen.orientation has patchy support, you can use the same media query in Javascript like so: Should you need to simply detect when a user changes orientation, you can use the following event listener: Currently, this is not supported in Safari, so your mileage may vary on this one.

How to detect when a user changes orientation in Safari?

Should you need to simply detect when a user changes orientation, you can use the following event listener: Currently, this is not supported in Safari, so your mileage may vary on this one. If you need to, you can use the matchMedia query from above to achieve similar functionality.

What happens when a class implements an interface?

If a class implements an interface, then all methods defined by that interface must be implemented (i.e. the guts of those functions should appear in the class). How do I define an interface?


2 Answers

Try [[UIApplication sharedApplication] statusBarOrientation].

like image 155
Mark Adams Avatar answered Sep 19 '22 00:09

Mark Adams


The proper way is to ask the device for its orientation as a view technically has no orientation. ;)

So you're correct in using UIDevice. From the documentation you can see that you first need to generate device orientation notifications before this information is correct. Then it will work as desired.

UIDevice *myDevice = [UIDevice currentDevice];
[myDevice beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation currentOrientation = [myDevice orientation];
[myDevice endGeneratingDeviceOrientationNotifications];

Note: This gives you the current orientation of the device. If the currently visible/top view controller did not allow rotation to this orientation, you will nevertheless get the current device orientation, not the one the topmost view controller currently uses.


Edit after question was updated:

You are correct that the orientation for the topmost view controller (worked correctly for subview controllers) always returns 1 (i.e. UIInterfaceOrientationPortrait) in loadView. However the method willRotateToInterfaceOrientation:duration: will immediately afterwards be called, and the orientation passed there is correct, so you should be able to use that method.

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toIfaceOrient
                                 duration:(NSTimeInterval)duration
like image 36
Pascal Avatar answered Sep 20 '22 00:09

Pascal