io6 allow interface orientation based on some condition - ios

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:

Related

How to rotate one view controller and others stay in one mode (portrait mode) in ios?

I have five view controllers and In Project Target Device Orientation I have enabled Portrait ,Landscape Left and Landscape Right. Now I want 4 view controllers out of 5 view controllers Stay in Portrait mode (Not Rotate into landscape left and landscape right) and only one view controller rotate in all modes(Portrait,landscape left,landscape right). So How can do this please tell .
Implement -(NSUInteger)supportedInterfaceOrientations for each of your ViewControllers and specify which interface orientations each controller should support.
Edit
Assuming that you have a separate implementation for each of your ViewControllers, implement -(NSUInteger)supportedInterfaceOrientations and -(BOOL)shouldAutorotate in each of your implementations.
For example
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
will ensure that your view controller supports all landscape modes. Combine this with
-(BOOL)shouldAutorotate{
return YES;
}
and your display will "flip" over when rotated.
Use the enum UIInterfaceOrientationMask to adjust which orientations are supported and try different combinations of this along with a YES/NO return value to -(BOOL)shouldAutorotate until you get the behaviour you want.
First of all, in AppDelegate, write this.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAll;
}
Then, For UIViewControllers, in which you need only PORTRAIT mode, write these functions
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
For UIViewControllers, which require LANDSCAPE too, change masking to All.
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
//OR return UIInterfaceOrientationMaskAll;
}
Now, if you want to do some changes when Orientation changes, then use this function.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
}
NOTE Please :-
A lot depends on with which controller is your UIViewController embedded in.
Eg, If its inside UINavigationController, then you might need to subclass that UINavigationController to override orientation methods like this.
subclassed UINavigationController (the top viewcontroller of the hierarchy will take control of the orientation.) did set it as self.window.rootViewController.
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
- (NSUInteger)supportedInterfaceOrientations
{
return self.topViewController.supportedInterfaceOrientations;
}
From iOS 6, it is given that UINavigationController won't ask its UIVIewControllers for orientation support. Hence we would need to subclass it.

Portrait in one viewController and landscape in another

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.

supporting Portrait Orientation mode for UIViewController in storyboard

I created UIViewController using storyboard and Linked it to UIViewController class.
I would like to make my UIViewController only support Portrait Orientation, I tried the blow code, but it seems it doesn't work. my UIViewController still rotate.
Do I need to change any property in storyboard?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
}
shouldAutorotateToInterfaceOrientation is deprecated in iOS6, you should use shouldAutoRotate & supportedInterfaceOrientations.
Try like this in your viewController.
- (BOOL)shouldAutorotate {
return NO;
}
- (BOOL)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
I found the answer here:
iOS 6 shouldAutorotate: is NOT being called
my UIViewControoller is managed by UINavigationController which control it orientation in iOS 6:
Now, iOS containers (such as UINavigationController) do not consult their children to determine whether they should autorotate. By default, an app and a view controller’s supported interface orientations are set to UIInterfaceOrientationMaskAll for the iPad idiom and UIInterfaceOrientationMaskAllButUpsideDown for the iPhone idiom.
I had to subclass UINavigationController with the new shouldAutorotate and supportedInterfaceOrientations
I saw other post prefer to add category instead of subclassing. but for me, subclassing works fine.

iPad orientation of iOS app - since new release

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.

How do I force a specific UIInterfaceOrientation on an individual view in a UINavigationController?

Okay, so here's the situation:
I have an app in which I only want ONE specific view in a UINavigationController to have a landscape orientation. This view is a UIImageView that I'm capturing a signature on (THAT part works awesome). So, like this:
previous view --> signature view --> next view
(portrait) (landscape) (portrait)
I can't seem to find a good way to force the device orientation to landscape on that signature screen. It'll never make sense to have a portrait orientation on the signature view because there's really not adequate room for signing in that screen width.
So, any bright ideas on how to accomplish this? I've considered possibly doing the signature view modally, thus breaking out of the navigation controller. Thoughts?
You can try to force Device to rotate to necessary orientation - but you need to handle it manually (in addition to overriding UIViewController orientation handling methods).
To rotate device you can use next methods:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
But in it may not work in all situations...
Also available undocumented approach:
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:")
withObject:(__bridge id)((void*)UIInterfaceOrientationLandscapeLeft)];
Just override this UIViewController method to only return true for landscape like so and the iphone will be forced to rotate to that device orientation, since it has no other option.
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Unfortunately, all root UIViewControllers inside of a Navigation Controller must support any of their child orientations. This means that the first view controller in your setup must support landscape, otherwise the child will only support portrait.
The best way to implement what you are looking for is to create a UIViewController that displays its content view on a rotated transform, and just default all UIViewControllers in that stack to portrait.
I think you can embed this view inside a view controller and overwrite the ShouldRotateToInterfaceOrientation method.
Good luck!
To use a View in only landscape, I have the following in the ViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
This might be what your looking for.
// Rotates the view.
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14159/2);
self.view.transform = transform;
// Repositions and resizes the view.
CGRect contentRect = CGRectMake(-80, 80, 480, 320);
self.view.bounds = contentRect;
from http://www.iphonedevsdk.com/forum/iphone-sdk-development/1394-landscape-uiviewcontroller-uiview-rotation.html
I have an app that has landscape only views that even starts in landscape. This was working fine in iOS 5.x but stopped working in iOS 6.x
After trying many many things, some more questionable than others, I found a solution that to me is clear and predictable.
I did several things.
-- I kept the views in landscape mode in IB.
-- I checked both landscape modes in the project settings - there a four icons there to control it
-- Orientation mgmt has changed in iOS 6.x. I had to overwrite a few methods to support changing to landscape
this method is for iOS 5.x
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations.
return (interfaceOrientation & UIInterfaceOrientationMaskLandscape);
}
these 2 methods are for iOS 6.x
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger supportedOrientations = UIInterfaceOrientationMaskLandscape;
return supportedOrientations;
}
- (BOOL)shouldAutorotate
{
return YES;
}
-- But the key was to change the logic in the AppDelegate. Original code I had there was adding a subview (controller.view) to the window. This stopped working in iOS 6.x - I changed the call to window.setRootController. That was the final step that sealed it - it would not work without making this final change
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//[self.window addSubview:viewController.view];
[self.window setRootViewController:viewController];
[self.window makeKeyAndVisible];
return YES;
}
The UINavigationController overrides the contain UIViewController orientation settings, so you have to create a custom subclass of UINavigationController with the following for 5.1:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[self topViewController] isKindOfClass:[SigCaptureViewController class]]) {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
} else {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
For 6.0 and above you need:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
if ([[self topViewController] isKindOfClass:[EXTRASigCaptureViewController class]]) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
What I haven't figured out is how to make the force the UINavigationController to rotate. calling [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO] causes the status bar to rotate but doesn't cause the view to rotate.

Resources