I know that there are lots of threads about how to force an orientation in IOS6 but none of them seems to work for me so now I need some help figuring this out.
I have a navigation based app that has many view controllers. All of them are in portrait view exept one that has to load in landscape mode (without having the user turning the phone first).
In the implementation of my navigation controller, I have added shouldAutorotate, supportedInterfaceOrientations and preferredInterfaceOriantationForPresentation.
#implementation UINavigationController (Rotation_IOS6)
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
#end
So it returns the values that have then defined in each view controller.
In the app delegate I have the supportedInterfaceOrientationsForWindow.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
//Default orientations value
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
//Get orientation from the last view controller
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
In each view controller I then have my settings for that view, for example:
// Only allow portrait view
-(NSInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate {
return YES;
}
And I push the next view controller like this:
NextViewController *nxtController = [[NextViewController alloc] initWithNibName:#"NextViewController" bundle:nil];
[self.navigationController pushViewController:nxtController animated:YES];
But when I push the landscape view controller, while holding the phone in portrait orientation, It also loads in portrait mode. If I then tilt the phone it triggers the autorotate function and rotates the view into landscape mode, and then it is locked in that mode. However I need to lock it in landscape mode without using the phones orientation to trigger it to check autorotate.
Any ideas?
You could try to force the viewController to show in landscape by using the shouldaAutorotateToInterfaceOrientation that always return landscape, such as:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
go to project settings and remove the selection on the modes you do not want.
Related
I'm attempting to set a view's orientation based on if the device is running on an iPhone or an iPad. I have a supportedInterfaceOrientations method, which I call from viewDidLoad:
[self supportedInterfaceOrientations];
In the supportedInterfaceOrientations method, I check if the device is an iPhone. If it is, the view should only be set to a portrait orientation. Otherwise, all orientations should be supported:
- (NSUInteger)supportedInterfaceOrientations
{
//If the device is an iPhone, we're going to make this page portrait-only
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskPortrait;
}
//If it's an iPad, we'll support all orientations.
else {
return UIInterfaceOrientationMaskAll;
}
}
However, when I run the app on an iPhone, the view does not stay locked in portrait mode, but will rotate based based on the phone's orientation. Does anyone have an idea of what I'm doing wrong? Thank you!
EDIT I forgot to mention that this particular view is part of a Navigation Controller, which I just realized is probably the cause of the problem.
EDIT2 The xib for this particular view is also set to 'portrait' in the 'Simulated Metrics' section. Additionally, below is the code where I build the view controller and present the view:
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.mainViewController];
self.navigationController.delegate = self;
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
Use:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
//If the device is an iPhone, we're going to make this page portrait-only
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskPortrait;
}
//If it's an iPad, we'll support all orientations.
else {
return UIInterfaceOrientationMaskAll;
}
}
I have a problem with my app. I cannot lock the orientation of my app. All I need to do is to lock one view controller to landscape mode and the rest are portrait.
This is hierarchy of my app.
*Navigation Controller
*TabBarController
*ViewControllers
You only have to return NO from shouldAutorotate and the landscape orientation from supportedInterfaceOrientation in the one you want to be in landscape.
On the other, return NO too from shouldAutorotate method and portrait orientations mask from supportedInterfaceOrientation.
In all the viewControllers :
-(BOOL)shouldAutorotate {
return NO;
}
In the one you want in landscape :
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
In the controllers you want in portrait :
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
Use below 2 this methods to lock device orientation to landscape.
- (NSUInteger)supportedInterfaceOrientations{
[super supportedInterfaceOrientations];
return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight)
{
return YES;
}
// Return YES for supported orientations
return NO;
}
With NavigationController
-(BOOL)shouldAutorotate
-(NSUInteger)supportedInterfaceOrientations
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
these method are never called , if you use 'show segue(push)'.
change segue 'showDetail' instead 'show'
I have embedded a UIViewController in a UINavigationController. The orientation of the view of this controller is set to Portait. When I push a new view on this UIViewController, which is landscape only, the new view is being shown portrait as well, instead of it's orientation landscape.
I have tried to subclass the UINavigationController and added the following methods like this:
- (BOOL)shouldAutorotate {
return self.topViewController.shouldAutorotate;
}
- (NSUInteger)supportedInterfaceOrientations {
return self.topViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return self.topViewController.preferredInterfaceOrientationForPresentation;
}
In the rootViewController (LoginViewController) I did this:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return YES;
}
In the pushViewController (A custom ViewController) I did this:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
-(BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft;
}
I'm using a storyboard and a push segue between them. I know that the problem lies in the push segue which leads to an taking over of the orientation of the topviewcontroller which is portrait and the pushViewController is landscape. Does anyboy know workarounds?
Any help is thankfully appreciated. Else I should drop the navVC and perform a modal segue.
KR
Try this code :
In AppDelegate.m class write below code.
#pragma mark Orientation Code
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
NSUInteger orientations = UIInterfaceOrientationMaskAll;
if (self.window.rootViewController) {
UIViewController* presented = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presented supportedInterfaceOrientations];
}
return orientations;
}
And next if you don't want orientation of the particular class for example
Stop orientation viewController.m
#pragma mark Orientation
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
final thing to change project device orientation of project Target.
Ex : Project TARGETS --> Device Orientation -- > select All (Portrait, UpSide Down, Landscape Left, Landscape Right)
My application is working fine for iOS5. But for iOS6 I am getting the following orientation problem.
I have a ViewController VC1. when you rotate (change the orientation to UIInterfaceOrientationLandscapeRight) I want to present another ViewController VC2 and when you rotate back I need to dismiss VC2 and the VC1 should be in Portrait mode.
I am using tabBar in my application and I want this feature only for the first tab.
In tabBar I have written
-(BOOL) shouldAutorotate
{
UINavigationController *nav = (UINavigationController *)self.selectedViewController;
if ([nav.topViewController isKindOfClass:[MainViewController class]])
{
return YES;
}
else
{
return NO;
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//Here I am writing code for presenting view(using notifications)
// but When I rotate the device to landscape it's getting called but when I rotate back
//to portrait I not getting called.
}
Thank you.
Please try this with ios 6 :(Example)
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait | UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
I'm presenting a modal view with the code:
[self presentViewController:movieViewController animated:YES completion:^{
// completed
}];
Inside movieViewController, the controller is dismissed with:
[self dismissViewControllerAnimated:YES completion:^{
// back to previous view controller
}];
At the moment, all my view controllers can be viewed in portrait and the two landscape orientations.
How would I restrict all view controllers to portrait EXCEPT the modal view controller? So the modal view controller can be seen in the three orientations, and everything else in one.
In appDelegate:
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
special UINavigationController subclass (if you using navigation controller) with methods:
- (NSUInteger)supportedInterfaceOrientations {
if (self.topViewController.presentedViewController) {
return self.topViewController.presentedViewController.supportedInterfaceOrientations;
}
return self.topViewController.supportedInterfaceOrientations;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return self.topViewController.preferredInterfaceOrientationForPresentation;
}
each view controller should return it's own supported orientations and preferred presentation orientation:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
my app works in portrait, but video player opens as modal vc with:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
It works perfect for me, hope it helps!