Frustrating. I've tried to make an app Portrait only.
In Targets => Summary => Supported Interface Options, only portrait is selected.
I've put the following on the navigation controller of my app:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate{
return NO;
}
And even copied the same onto the root view controller of the navigation controller. It's still being presented that the view is allowed to be rotated. I'm still able to rotate my app to landscape on the iPad, and possibly even upside down on the iPhone.
Thanks!
Related
I have a universal iOS (7.1+) app that I would like to only support portrait orientation for most views. I would like 1 view to autorotate.
The application is a navigation based application (i.e. the base view is a UINavigationViewController). In the project editor under Deployment Info I have checked portrait, landscape left and landscape right as the supported orientations.
I then restricted the autorotation of the app by implementing the -(BOOL)shouldAutorotate method and the - (NSUInteger)supportedInterfaceOrientations in my base navigation controller. As I understand it, this will restrict the orientation in any view displayed by the navigation controller.
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
The view I would like to autorotate I present modally. In the view controller that I present modally I also set -(BOOL)shouldAutorotate and - (NSUInteger)supportedInterfaceOrientations.
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait;
}
This solution works fine on iPhone! The one modal view rotates as expected and the other views inside the However, the same view using the same code does not rotate on the iPad. I am confused as to why it works on the iPhone and not on the iPad. It seems to me that since it is the exact same view controller that it should rotate on both.
My app has this main structure: UITabBarController, where each tab hosts a UINavigationController that pushes views according to user interaction. Almost all the app is portrait orientation only, except a few specific sections.
The behavior I want is to have landscape orientation when I push one of the sections (let's say a map). In that map, the user can go back to portrait orientation. When he goes back in the main menu, he should go back to portrait orientation (landscape should not be allowed here). I don't mind if he is temporarily in landscape.
Here's some code from my UITabBarController subclass:
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
I use the same code in my UINavigationController, and in the specific menu, I have this:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
- (BOOL)shouldAutorotate
{
if (!UIInterfaceOrientationIsPortrait([[UIDevice currentDevice] orientation]))
return NO;
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
The behavior works almost all the time. When the orientation of the menu is landscape and the user rotates his device, he goes back to portrait, but can't go back to landscape.
My issue is: once in a while, the status bar will rotate, but not the view controller. (see picture) Each time, shouldAutorotate is called and returns the correct value (ie. it returns YES but does not autorotate).
I know this is stretching the SDK, but I'd love to make this work all the time. Any hints?
I have following ViewControllers:
InformationViewController and cardViewController.
How can i make sure that informationViewController is in portrait mode and cant be rotated.
Then cardViewController should be in landscape mode and cant be rotated.
How can i implement this in each viewController. i've at the moment activated protrait, landscape right and left in General
In Information view controller
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And in card view controller
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Note: Please be sure in project general setting tick the both portrait and landscape modes in device orientation (Deployment Info)
In informationViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
In cardViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscape);
}
Have a look at my answer to this question:
Force controllers to Change their orientation in Either Portrait or Landscape
(But don't use the deprecated methods. There are newer methods available which work either.)
It is easy to limit the view controllers to certain orientations. But see the other answer for how to force the device to actually rotate.
Without that trick: If a portrait only view controller becomes visible while the device is in landscape, then it will be displayed in landscape regardless how you limit its supported orientations.
I have a flag and user will set it from setting. If set to No only portrait orientation will be allowed. If flag is YES then both portrait as well as landscape will be allowed.
in ios 5 and below
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
//[image_signature setImage:[self resizeImage:image_signature.image]];
if(flag == YES)
return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationPortrait);
else
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
But in ios 6 and above above method deprecated.
I was trying
-(BOOL)shouldAutorotate
- (NSUInteger)supportedInterfaceOrientations
But no success.
Please help me.
EDIT
I tried this.
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
NSLog(#"preferredInterfaceOrientationForPresentation");
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)supportedInterfaceOrientations
{
NSLog(#"supportedInterfaceOrientations");
return UIInterfaceOrientationMaskPortrait;
}
But only supportedInterfaceOrientations is called only once. When I change orientation of simulater both methods not calling.
shouldAutorotateToInterfaceOrientation:
Returns a Boolean value indicating whether the view controller supports the specified orientation.
(Deprecated in iOS 6.0. Override the supportedInterfaceOrientations and preferredInterfaceOrientationForPresentation methods instead.)
(http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html)
So the two method you can use in newer versions are:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/preferredInterfaceOrientationForPresentation
and
- (NSUInteger)supportedInterfaceOrientations
This method uses the following Bit Masks:
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortraitUpsideDown
UIInterfaceOrientationMaskLandscape
UIInterfaceOrientationMaskAll
UIInterfaceOrientationMaskAllButUpsideDown
http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/supportedInterfaceOrientations
Update:
OK, I'm not sure why it isn't working for you.
I've just created a demo app to replicate what you're trying to do:
(use right click > copy image url and open in new browser tab to see bigger picture)
When the orientation flag is NO, the button text shows "Landscape Denied", and rotating the device in simulator doesn't cause interface to rotate, as expected:
However after clicking on the button to allow landscape orientation, rotating the simulator device actually changes the orientation of the interface, as expected:
You don't have any other orientation delegate method in another root view controller overriding your current view controller's orientation delegate methods do you?
Also, I don't know if using Auto Layout interferes or not, I tend not to use it. In my View inside my XIB file, I selected the "View" object and then in the inspector, I untick "Use Auto Layout". My example project screenshot above is NOT using auto layout.
Update 2:
Alright, I found this solution which worked with navigation controller as root view controller of window (put this in your AppDelegate.m):
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
NSUInteger orientations =UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController)
{
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
in this Stackoverflow post:
iOS 6 AutoRotate In UiNavigationController
New screenshot with navigation controller:
Last time I ran an iOS app I made, it must have been on for deployment target 5.0 and the associated SDK (there's a chance it could have been as early as 4.3). The deployment is now 6.1. My app only runs landscape and worked fine in landscape. But after I updated my iPad and iOS SDK and ran this app for the first time in about a year, it seems something has changed.
The buttons show up as if the iPad is in portrait mode. This is wrong, because it should be in landscape (and it used to work just fine).
What has changed in the newest updates?
My supported interface orientations in Xcode have "Landscape Right" selected only and in the Info section I have "Supported interface orientations" with just a single Item: "Landscape (right home button)".
In my main view control that opens when the app first opens, I have
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
and also the first line of the viewDidLoad is
self.view.frame = CGRectMake(0, 0, 1024, 768);
So why is the code drawing buttons as if it is in Portrait mode?
UPDATE
I have tried to replace the shouldAutorotateToInterfaceOrientation method with
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationLandscapeRight & UIInterfaceOrientationLandscapeLeft;
}
but it still doesn't work.
Orientation changes in iOS6.0
You should implement the following methods
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
// Set the initial preferred orientation
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
Note
If you are using TabBarController/NavigationController you should sub class those view controller to override the orientation methods in such a way that it should call your own view controller methods. This is a significant change in iOS6.
#import "UINavigationController+Orientation.h"
#implementation UINavigationController (Orientation)
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
shouldAutorotateToInterfaceOrientation is deprecated in iOS 6, you should override
supportedInterfaceOrientations method of UIViewController
There is quote from doc:
In iOS 6, your app supports the interface orientations defined in your
app’s Info.plist file. A view controller can override the
supportedInterfaceOrientations method to limit the list of supported
orientations. Generally, the system calls this method only on the root
view controller of the window or a view controller presented to fill
the entire screen; child view controllers use the portion of the
window provided for them by their parent view controller and no longer
participate in directly in decisions about what rotations are
supported. The intersection of the app’s orientation mask and the view
controller’s orientation mask is used to determine which orientations
a view controller can be rotated into.
You can override the preferredInterfaceOrientationForPresentation for
a view controller that is intended to be presented full screen in a
specific orientation.