How to show one view controller in landscape mode? - ios

HI I'm using below code for Landscape Mode for only one view controller
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight; // or Right of course
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
It is working fine But when i rotate to Portrait Then it is rotating and i'm using below code for presenting the view
[self presentViewController:vc animated:YES completion:nil];
where I'm Missing Thanks in advance

Use this code
In your AppDelegate.h
#property (assign, nonatomic) BOOL shouldRotate;
AppDelegate.m
BOOL shouldRotate;
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if (self.shouldRotate)
return UIInterfaceOrientationMaskAllButUpsideDown;
else
return UIInterfaceOrientationMaskPortrait;
}
Now open your ViewController in which you want to apply orientations and use this code
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:YES]; // set NO to disable rotation

Related

How to detect orientation of View Controller

I have three view controller both are which are pushed on the navigation controller which I have subclassed in order to allow rotation in only Second View Controller, I do it like this,
- (BOOL)shouldAutorotate
{
if ([self.topViewController isKindOfClass:[SecondViewController class]])
return YES;
return NO;
}
I write this piece of code in my Custom Navigation Controller, The problem is that if I open my application in portrait mode and then change the orientation to landscape mode my View Controller does not rotate but even when my Second View Controller opens up it opens in portrait mode although I expect it to open in landscape mode as it supports rotation.
How can I achieve this?
You need to use attemptRotationToDeviceOrientation during navigation. You should override push/pop methods to call attemptRotationToDeviceOrientation with a small UI delay (dispatch_async)
#implementation CustomNavigationController
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[super pushViewController:viewController animated:animated];
[self updateOrientaion];
}
- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated
{
[self updateOrientaion];
return [super popViewControllerAnimated:animated];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if ([self.topViewController isKindOfClass:[SecondViewController class]])
return UIInterfaceOrientationMaskAll;
return UIInterfaceOrientationMaskPortrait;
}
- (void)updateOrientaion
{
dispatch_async(dispatch_get_main_queue(), ^{
[UIViewController attemptRotationToDeviceOrientation];
});
}
#end
But when you pop to rootViewController of the UINavigationController supportedInterfaceOrientations is called for the rootViewController. So you also need to implement supportedInterfaceOrientations for the FirstViewController
#implementation FirstViewController
.......
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
#end

change one view orientation to landscape

I'm working on a project in which user will watch live channels. But I'm facing a small problem here and I've tried very hard but failed to find any solution. My app will support portrait orientation for all views but last one. Last view will support only landscape orientation. Is it possible?
I've searched and tried following code
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
//
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
//
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);}
Follow this link. Hope you get your answer here.
The link shows how to keep all your views in portrait mode except one view that will be in landscape.
You need to do the following:
1st :
Implement this in all controllers that are fix for portrait:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And implement this for the landscape controllers:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
2nd :
// Fetch the status bar from the app and set its orientation as required.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
// Create an empty view controller, present it modally and remove it directly afterwards
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
// Now the device is rotated to the desired orientation. Go from there.
Hope that works.
From iOS6 apple has changed orientation update mechanism. From iOS6 onwards, iOS will report orientation event only to RootController, so all the orientation related decision can only be taken in RootController. Lets say you are using UINavigationController or UITabBarController as window's root controller. In this case you can create sub class of UINavigationController or UITabBarController, override orientation related methods and pass orientation related events to childControllers. Set this custom UINavigationController or UITabBarController object as rootController of your window.
You can override below methods in your custom class.
-(BOOL)shouldAutorotate
{
BOOL shouldRotate = YES;
if(self.viewControllers.count > 0)
shouldRotate = [[self.viewControllers lastObject] shouldAutorotate];
return shouldRotate;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSUInteger supportedInterfaces = UIInterfaceOrientationMaskAll;
if(self.viewControllers.count > 0)
supportedInterfaces = [[self.viewControllers lastObject] supportedInterfaceOrientations];
return supportedInterfaces;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation preferredOrientation = UIInterfaceOrientationPortrait;
if(self.viewControllers.count > 0)
preferredOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
return preferredOrientation;
}
Use Following approach : In your app delegate .h
#interface PlayWithWSWithLibAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
BOOL flagOrientationAll;
}
#property (assign) BOOL flagOrientationAll;
Add following method in your app delegate .m file
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
//NSLog(#"PlayWithWSWithLibAppDelegate -- supportedInterfaceOrientationsForWindow");
if(flagOrientationAll == YES){
return UIInterfaceOrientationMaskLandscapeRight;
} else {
return UIInterfaceOrientationMaskPortrait ; // your Default orientation for all other view
}
}
Implement following way in your view which you want to rotate in both portrait and landscape both for iPhone device
-(void)viewWillAppear:(BOOL)animated
{
self.tabBarController.delegate = self;
PlayWithWSWithLibAppDelegate *delegate = (PlayWithWSWithLibAppDelegate *) [[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = YES;
}
}
-(void)viewWillDisappear:(BOOL)animated
{
//NSLog(#"viewWillDisappear -- Start");
PlayWithWSWithLibAppDelegate *delegate = (PlayWithWSWithLibAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = NO;
}

Orientation doesn't change after Pushing (push segue) a View on the UINavigationViewController

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)

Maintain one view controller in Portrait and other in Landscape mode iOS

I have an iOS app with 2 view controllers namely - FirstViewController and SecondViewController. My window's rootViewController is UINavigationController.
FirstViewController is supposed to work ONLY in portrait mode and SecondViewController ONLY in Landscape mode.
Searching all over Stackoverflow I found out that for iOS6 and above I have to create a category over UINavigationController and override -supportedInterfaceOrientations
THE PROBLEM
Starting from FirstViewController. Now my phone being in Portrait mode, I push SecondViewController, the view loads in portrait mode. Once I rotate my phone to be in landscape the view will rotate to landscape ( and from this point onwards will not return to portrait at all ).
When I pop back FirstViewController will be in Portrait again ( no matter what the orientation of the phone ).
I want that SecondViewController shouldn't be displayed in Portrait mode at all. I've racked my brains all day...cannot find a solution.
APPDELEGATE
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController *vc = [[ViewController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
[self.navigationController setNavigationBarHidden:YES];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
FirstViewController
- (IBAction)btnClicked:(id)sender
{
SecondViewController *vc = [[SecondViewController alloc] init];
[self.navigationController pushViewController:vc animated:NO];
}
#pragma mark - Rotation handlers
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
SecondViewController
- (IBAction)btnClicked:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - Rotation handlers
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
UINavigation Category
#implementation UINavigationController (Rotation)
-(BOOL)shouldAutorotate
{
//return [self.topViewController shouldAutorotate];
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
#end
Well, it's a bit late but here is what I figured.
While there are many solutions available for the case when FirstVC is Portrait and Second can be Portrait and Landscape, I couldn't find any good solution to this problem (First Portrait ONLY and Second Landscape ONLY). Here is what I did:
Embed both view controllers in their own Navigation Controllers. Create two new classes, say FirstNavController and SecondNavController subclassing UINavigationController. Use these as your navigation controllers. (If you are using StoryBoards, select the Navigation Controller, go to Identity Inspector and change 'Class' field).
Now, in FirstNavController, add:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And in SecondNavController:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
You will have to present the SecondNavController modally.
Nothing needs to be done in your View Controllers. Make sure you add all required orientations in your application settings.
The only drawback of this method is that both views are not in the same navigation stack, as second was presented modally, so you won't see a back button. But you can add a cancel/dismiss button yourself and call dismissViewControllerAnimated in SecondVC.
in my previous app i have done it
first you need to enable Portrait , Landscape left , Landscape right Orientation to project
Now
set below code to your FirstViewController
-(void) viewWillAppear:(BOOL)animated{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
}
- (BOOL)shouldAutorotate
{
return NO;
}
set below code to your secondViewController
#define degreesToRadian(x) (M_PI * (x) / 180.0)
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
#end
#interface secondViewController ()
#end
#implementation secondViewController
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
#end

1st ViewController in Portrait and SecondViewController in Landscape Mode

My requirement is this my 1st viewcontroller open in Portrait mode only.and when user goes to 2nd viewcontroller i want that controller in Landscape mode how may i do this
i tried this code
1st ViewController.m
- (BOOL)shouldAutorotate
{
returnc YES;
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
{
return (interface==UIInterfaceOrientationMaskPortrait);
}
Code for 2nd ViewController.m
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
//return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
this will not working fine for me.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsPortrait(toInterfaceOrientation);
}
UPDATED:
You can do this by creating category of UINaviagationController
code for .h file is
#interface UINavigationController (autorotation)
-(BOOL)shouldAutorotate;
-(NSUInteger)supportedInterfaceOrientations;
and code for .m file is
#implementation UINavigationController (autorotation)
-(BOOL)shouldAutorotate
{
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
[self.topViewController shouldAutorotate];
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#end
paste following code in viewcontroller .m file of second view controller (under #implementation section)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Now select the second view controller in storyboard (Selection indicated by blue border around view controller), go to the attribute inspector (right side 'shield' like image) change the orientation to landscape.. That's it.. .Tell me if it doesn't work for u. ..:)
I am solving my problem using Category....
Add new files and select Category and make subclass UINavigationController class.
here is the code for category for .h
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#interface UINavigationController (orientation)
#end
code for .m file
#import "UINavigationController+orientation.h"
#implementation UINavigationController (orientation)
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
if (delegate.islandscape)
{
// for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
return UIInterfaceOrientationMaskLandscape;
}
return UIInterfaceOrientationMaskPortrait;
}
#end
isLandscape is declared in App delegate to check weather First view controller or secondView Controller isLandscape is Bool.
Now FirstViewController.m file i want that in Portarit mode so used this code
- (IBAction)PlayClicked:(id)sender
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
self.navigationController.navigationBarHidden=YES;
delegate.islandscape=YES;
ViewController * v=[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self presentViewController:v animated:NO completion:nil];
//[self dismissViewControllerAnimated:YES completion:nil];
[self.navigationController pushViewController:v animated:YES];
}
- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
and SecondViewController i want that in Landscape mode used this one.
delegate.islandscape=NO; // called transfer to Category
- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}

Resources