IPhone Frequently Asked Questions and Solutions

There was a lot of confusion and a set of relevant sets of questions about how iPhone applications with the correct processing for autorotation in Landscape / Portrait mode can be implemented. It is especially difficult to implement such an application when you want to start in landscape mode. The most common observed effect is scrambled layouts and areas of the screen on which strokes are no longer recognized.

A simple search for questions with the tags iphone and landscape reveals these problems that occur in certain scenarios:

  • Landscape is just an application for the iPhone with several tips : The application started in landscape mode, the view from the first nib is displayed perfectly, all images downloaded from another nib are not displayed correctly.

  • Iphone Landscape mode in Portraite mode when loading a new controller: Self-evident

  • iPhone: only in the landscape, after the first addSubview, the UITableViewController does not rotate correctly : the same problem as above.

  • IPhone landscape-only web application : layout errors, the controller does not seem to recognize that the view should be rotated, but displays the cropped portrait view in landscape mode, leaving half of the screen blank.

  • presentModalViewController in the landscape after portrait viewing Controller: Modal views also do not display correctly.

A set of different solutions is presented, some of which include fully custom animation through CoreGraphics, while others rely on the observation that the first view controller loaded from the main nib always displays correctly.

I spent a considerable amount of time studying this problem and finally found a solution that is not only a partial solution, but should work under all these circumstances. I intend with this CW post to provide some FAQ for others having problems with UIViewControllers in landscape mode.

Please provide feedback and help improve the quality of this Post by including any related observations. Feel free to edit and post other / best answers if you know about them.

+18
iphone uiviewcontroller orientation landscape
Jun 01 '10 at 21:08
source share
6 answers

What's in the documentation :

In your view controller, override shouldAutorotateToInterfaceOrientation: declare your supported interface orientations. This property will / should be checked by the controller infrastructure every time the device orientation changes.

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { return (orientation == UIInterfaceOrientationLandscapeRight); } 

This is the absolute minimum that your controller must fulfill. If you want to run the application in landscape mode, you need to add the following file to the .plist file:

 <key>UIInterfaceOrientation</key> <string>UIInterfaceOrientationLandscapeRight</string> 

Apple recommends that you only run landscape applications in Landscape mode (see HIG under User Guides> Start Instantly.

What's not in the documentation:

A bit of background:

Each time you try to load a different view controller other than the one loaded from the main nib, your view controller does not examine its supported interface orientations and does not set its frame. Only the first view controller associated with the window will be correctly installed.

Other people have suggested using a "MasterViewController" connected to the main window, to which other controllers add their subview views instead of connecting directly to the window. Although I found that this solution is a viable option, it does not work correctly in the case of modal view controllers added to these specified areas. There is also a problem if you have some subitems that should be able to autorotate (which will prevent the main controller).

Using an undocumented API to force orientation of an interface is also not an option.

Decision:

The best solution I have found so far is a modification of the "MasterViewController" workaround. Instead of using the custom "MasterViewController", a UINavigationController with a hidden navigation bar and a hidden tab bar is used. If all other views are popped / pulled out of the navigation stack of this controller, the control of the controller rotations in this stack will be correctly executed.

Modal controllers presented via presentModalViewController:animated: from any of the view controllers in the UINavigationController navigation stack will be rotated and displayed with the correct layout. If you want your modal view controller to rotate in a different orientation than the parent view controller, you need to return the desired orientation from the shouldAutorotateToInterfaceOrientation method of the shouldAutorotateToInterfaceOrientation controller, while the modal view is Presented. In order to correctly restore the orientation of the interface when the modal controller is disabled, you must ensure that shouldAutorotateToInterfaceOrientation returns the desired orientation of the parent controller before calling dismissModalViewController:animated: To control this (e.g. BOOL isModalMailControllerActive_ ), you can use the private BOOL on your view controller.

Soon I will add part of the sample code. This is only the end. Please let me know if there are any unresolved issues or if something is not clear in this post. Feel free to edit and improve.

+13
Jun 01 '10 at 21:44
source share

I had an interesting requirement for an ios application:

main viewController should only be a landscape, but all others (which can be clicked from the main) can be landscape and portrait.

The occours problem is when I click on the new viewController, which then rotates to the portrayable - and pop-up - main view is no longer landscape. Also - the opening of the application, it is not in the landscape.

To preserve the main landscape of the viewcontroller, no matter what orientation it popped up / clicked, I did the following: (in viewWillAppear :)

 //set statusbar to the desired rotation position [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO]; //present/dismiss viewcontroller in order to activate rotating. UIViewController *mVC = [[[UIViewController alloc] init] autorelease]; [self presentModalViewController:mVC animated:NO]; [self dismissModalViewControllerAnimated:NO]; 

Hope this helps someone!

PSTested on sdk 3.2.5 ios 5.0.1.

PS Thanks for all the information in this FAQ!

+7
Apr 13 '12 at 18:24
source share

For the second marker point, if you want to use pushViewController to switch from "Portrait only" to "Landscape" mode, I found one simple hack to put the following code into your pressed viewDidLoad controller:

 UIViewController *viewController = [[UIViewController alloc] init]; [self presentModalViewController:viewController animated:NO]; [self dismissModalViewControllerAnimated:NO]; [viewController release]; 
+3
Oct 29 '11 at 7:33
source share

I would like to add to Johannes answer (using the UINavigationController as MasterViewController).

The disadvantage I discovered is that ViewControllers, which have recently been clicked on the VC main navigation stack, do not correct any orientation changes. In short, the VCs already on the stack are rotated, the modal view controllers represented by them also rotate, but the newly added VCs do not rotate.

I tried many tricks to fix this before finding the one that works. Works best for pushViewController: with animated typing in YES.

To completely fix the problem, I subclassed the UINagivationController and redefined pushViewController:animated: as follows:

 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { // Correctly autoOrient the given view controller [self presentModalViewController:viewController animated:NO]; [self dismissModalViewControllerAnimated:NO]; // Push it as normal (now in its correct orientation) [super pushViewController:viewController animated:animated]; } 

Temporarily (and completely imperceptibly), displaying the view controller, allows you to receive its orientation update. Then it can be moved to the navigation stack in the correct orientation.

Please let me know if this works for you. All updates and improvements are welcome!

Finally, I highly recommend Johannes' approach to rotation management.

EDIT: update when view controllers appear from the stack

It seems that all the selectors associated with popViewController go crazy when executed with animated ones: YES. In particular, the view controller is animated in the wrong direction. You can use animated: NO and restrict the use of such animations to other UINavigationControllers deeper in your hierarchy (i.e. those that you click on the root panel of the navigation controller).

Any input is welcome.

+2
Mar 16 '11 at 15:09
source share

I am developing an iPad application that displays a vertical scrollable gallery view of an array of elements at startup. In landscape mode, there are 4 items. There are three in the portrait. When you turn the orientation of the iPad, it is supposed to update the gallery so that the elements are neatly located on the screen. Then I double click on an element to go to the modal view of this element. Then I do things with this subject. Finally, I reject the modal view.

When updating or changing the orientation in the gallery view, the number of elements to be displayed is calculated depending on the width (height) of the screen and the current orientation from UIViewController.interfaceOrientation.

I have a problem with this to work correctly. Sometimes, after I rejected the modal dialog, it will display only two elements in landscape orientation.

First, I used the values โ€‹โ€‹of UIViewController.view.frame.size to calculate the number of gallery elements. When the modal representation was rejected, this frame size was incorrect, for example. the width and height were canceled, although the orientation did not change when the modal dialog was displayed.

I switched to using the application delegate ([[UIApplication sharedApplication] delegate]] and took window.frame.size to calculate the number of gallery elements to be displayed across. Window.frame.size remains correct with respect to orientation changes and modal dialogs. Elements galleries are displayed correctly.

+2
Dec 12
source share

It will work ...

 UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view]; 
-3
Oct 22 '12 at 11:40
source share



All Articles