I have a very old app that's compatible with iOS 3.2+ devices (both iPads and iPhones). And I have a big issue making it compatible with iOS 7!
In fact, it has been written long ago before ARC, storyboards and all that syntactic sugar we are pleased to play with nowadays. And I'm having a very hard time trying understanding some interface orientation issue:
For the iPhone, the app is only visible in landscape... No problemo with the main ViewController. But the settings one (a simple ViewController with a UITableView in it) is always displayed in Portrait !!! Whatever the properties I set and the methods I write.
In the .plist I have only supported orientations LandscapeLeft and Right. In the Settings View Controller, I have those methods:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsLandscape(interfaceOrientation) || (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
}
- (BOOL) shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)?UIInterfaceOrientationMaskLandscape:UIInterfaceOrientationMaskAll;
}
But what really bothers me is that when I display self.interfaceOrientation it says Landscape (in the viewWillAppear, viewDidAppear and viewWillLayoutSubviews).
But the most weird, is that the status bar is in Landscape, over the Portrait ViewController!!!
(Of course, the problem appears both on device and simulator)
So if someone can help putting back that ViewController all in Landscape. Thanks in advance!
Well at last, I eventually found it!!!
The problem was (I still don't know exactly why) caused by the way I was switching between ViewControllers (the old iOS 3 way).
So to correct if, I test if the method presentViewController:animated:completion is available (God bless respondsToSelector:) and I use it when I can.
Problem solved!
Related
I'm new to IOS development, and I'm trying to write an app for deployment on an ipad. Partly to keep things simple, layout-wise, and because I believe that my users will only use the app in landscape mode, I wish to only allow landscape views, and completely disable portrait views.
I've found a good deal of advice looking around the internet for an answer. Unfortunately, none of it has worked for me. The best answer I've found was to simply to go the target in xcode, and under "deployment info" -> Device Orientation, simply uncheck "Portrait" and "Upside Down". This should, theoretically, solve my issue, but unfortunately, it does not. The view rotates just as normal to portrait mode.
Going to the info tab and setting the Initial Interface Orientation to Landscape (Left) does make the app at least start in Landscape mode, but it does not restrict it only to that mode.
Even adding
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
into my main view doesn't seem to help anything. So I'm somewhat stumped. There must be some setting or something somewhere which is still allowing portrait views. What might this problem be?
If you look at your AppName-Info.plist file, there should be a key titled 'Supported interface orientations'.
You should remove any of the Portrait values in that dictionary and make sure you only have the Landscape values included!
Edit:
In the question-asker's case, their issue involved a piece of code in the AppDelegate that changed the app's supported orientations.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
/* They had the following:
* return UIInterfaceOrientationMaskAll;
* Which allowed the orientation to rotate to portrait
*/
// This fixed their issue:
return UIInterfaceOrientationMaskLandscape;
}
Hope this helps!
You can do this in General tab in your project
I have just completed building a universal app which rotates perfectly on my iPhone, but on the iPad it just stands still.
Similar to this question, but that does not solve my issue.
The supported interface orientations are all set to allow rotation and I have even set this in my app delegate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
Still the iPhone rotates fine, but the iPad won't move from portrait.
What could cause this, or rather how can I fix it?
[UPDATE]
The switch on the side is not on lock.
The orientations in the PList are set correctly.
The Project settings (where you select it via buttons) are set correctly.
#adam-s was right, except with Xcode 7.x there is no button below the "devices" selector.
With Xcode 7, you need to change "Universal" to "iPad" whereby the orientation selectors change to reflect iPad-only settings. Then you can change the selector back to "Universal".
Confusing!
Don't forget to change the rotation settings for the target for both iPhone and iPad - note that there's an iPad button to the right of the iPhone one (which some people, such as myself, might miss at first glance):
I fixed this by adding this piece of code to every ViewController of mine:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
It seems like this question's answer was correct after all. I just thought it wasn't since I checked through all the ViewControllers and found nothing restricting it from turning.
My app only supports landscape orientations via the supportedInterfaceOrientation properties.
Using an iOS prior to iOS 6, my app can successfully load an instance of UIImagePickerController via presentViewController:animated:completion: even though the UIImagePickerController itself only supports portrait orientation.
The image picker simply presented itself sideways to the user. The user rotated the phone, picked their image, and then rotated back to landscape.
Under iOS 6.0, calling presentViewController:animated:completion: with the UIImagePickerController instance crashes the app. I can prevent the crash by adding portrait options to my supportedInterfaceOrientation properties.
However, operating in portrait really does not make sense for my app. I had thought I could use shouldAutorotateToInterfaceOrientation to allow the app to "support portrait" but only be allowed to rotate to portrait in this one view. But now that method is deprecated, and I can't use the same technique with shouldAutorotate.
Does anyone have any ideas how I can get around this issue under iOS 6.0?
iOS 6.1 - fixed
As of iOS 6.1, this no longer occurs, it is very important to follow my tips in order to avoid a crash under iOS 6.0.x, the below still applies to that.
iOS 6.0.x workaround
This is in actual fact a bug in iOS 6.0, this should be fixed in future iOS releases.
An engineer from Apple has explained this bug and a workaround here: https://devforums.apple.com/message/731764
This is happening because the Application wants landscape orientation only but some Cocoa Touch View Controllers require strictly Portrait orientation which is the error - not that they should be requiring more then Portrait but their interpretation of the Applications requirements.
An example of this can be the following:
iPad app supporting landscape only displays a UIImagePickerController
via a UIPopoverController. The UIImagePickerController requires
Portrait orientation, but the app is forcing landscape only. Error
and... crash
Other frameworks that have been reported as problematic include the Game Center login view controller.
The workaround is pretty simple but not ideal... You keep the correct orientations declared in your info.plist/project info pane, but in the Application Delegate class you declare that you allow all orientations.
Now each View Controller you add to the window must specify itself that it can only be Landscape. Please check the link for more details.
I cannot stress how much you should not be subclassing UIImagePickerController as the accepted solution is insisting you do.
The important thing here is "This class is intended to be used as-is and does not support subclassing."
In my case I added this to my application's delegate (I have a landscape only app), this tells the image picker it can display, because portrait is supported:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
And then in my view controller which happened to be a UINavigationController, I included a category with the following:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
Now my app doesn't rotate, and the image picker asks the delegate if it can display as portrait and it gets told that's okay. So all plays out well.
I had a similar issue, but in an iPad landscape app. I was presenting the image picker in a popover. It crashed under iOS 6. The error suggested that the picker wanted portrait, but the app only offered landscape views, and ... importantly ... the picker's shouldRotate was returning YES.
I added this to my ViewControllerClass.m that is creating the picker
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate
{
return NO;
}
#end
and then used that class instead
UIImagePickerController *imagePicker = [[NonRotatingUIImagePickerController alloc] init];
[myPopoverController setContentViewController:imagePicker animated:YES];
That solved the problem for me. Your situation is a bit different, but it sounds like fundamentally the same error.
While subclassing UIImagePickerController works, a category is a better solution:
#implementation UIImagePickerController (NonRotating)
- (BOOL)shouldAutorotate
{
return NO;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
#end
Reporting from iOS 7.1:
In addition to what the above answers specify it seems that you have to absolutely enable portrait modes in the info.plist.
Without this none of the above code/fixes worked for me.
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Will fix the issue but from iOs7
I have downloaded an example code from here and tested it out. The thing I wasn't able to understand is that when I set the orientation to Landspace only and run it in Portrait mode, nothing changes.. I mean I should still be able to see the menu on left and the Psychologist button shouldn't be there.
PS: With iOS6, it is working well but lower versions giving me the same result.
It looks like in the RoatatableViewController.m file the method
- (BOOL)shouldAutorotateToInterfaceOrientation:
Is telling the app that rotation is okay in all directions.
You should use this to block to landscape mode for iOS 5 and older:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
It just looks like the person who made this project up in Stanford overlooked this.
I'm using Xcode 4.3.2 and an iPad simulator 5.1
I really need some help with this, my app is stuck at portrait mode.
When I rotate the simulator
I've tried looking under the project settings and have these checked:
Portrait, Upside Down, Landscape Left and Landscape Right.
I also these methods in the view controllers:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
can anyone please help?
Check your supporting orientations in the project's settings or on *.plist file. Also, if you are using UITabBarController or smth else, all of your controllers have to support all orientations!
use cmd+shift+f and type - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
make sure all of them return YES if you want all orientations supported and NO For unsupported orientations
Make sure you only have one controller showing. I've seen this problem when I have multiple views with different controllers showing at the same time.
Yeah I had the same problem and the other answers here didn't fix my situation. I found I had to check the "Resize View from NIB" box in all the relevant views.
See screenshot below (although shows a slightly older version of XCode).