change one view orientation to landscape - ios

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;
}

Related

How to show one view controller in landscape mode?

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

Return to portrait after landscape view

I have an application that need to be on portrait orientation for all view, and one view (UIWebview) that need to support portrait and lansdscape orietation.
To set the default portrait orientation , I put this in my app delegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
//NSLog(#"PlayWithWSWithLibAppDelegate -- supportedInterfaceOrientationsForWindow");
if(flagOrientationAll == YES){
return UIInterfaceOrientationMaskAll;
} else {
return UIInterfaceOrientationMaskPortrait;
}}
And I have manage to arrange my webview to portrait/landscape regarding the user orientation using this method (got this from stackoverflow also)
-(void)viewWillAppear:(BOOL)animated
{
AppDelegate *delegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = YES;
}
-(void)viewWillDisappear:(BOOL)animated
{
//NSLog(#"viewWillDisappear -- Start");
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = NO;
}
And to present portrait and landscape i using two UIView:
-(void)viewWillLayoutSubviews {
BOOL layoutIsPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation);
if (layoutIsPortrait) {
self.view = self.pView;
[self.pView addSubview:pwebView];
}else{
self.view = self.lView;
[self.lView addSubview:lwebView];
}}
Then to dismiss the webview i using this code:
- (IBAction)doneButtonTapped:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
However when it dismiss in landscape state, the previous screen (the screen that call the webview) present in landscape instead of the default(portrait).
How i can make after the webview dismiss it will still present in portrait?
thanks
You should implement the supported orientation for each viewController:
Like i wrote here:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
//Choose your available orientation, you can also support more tipe using the symbol |
//e.g. return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight)
return (UIInterfaceOrientationMaskPortrait);
}
Swift 3.0:
(Added to the ViewController that calls the landscape-able view)
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}

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

Landscape-only app still autorotates to portrait in iOS7

After updating to iOS7, my app shows autorotation.
I want it to be a landscape-only app and, accordingly, I set up everything as follows:
In iOS6 was fine.
In .plist file:
In my MainWindow controller
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
The AppDelegate.m call it as:
MainViewController* mainViewController = [[MainViewController alloc] init];
// Create the navigation controller
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:mainViewController];
[navController setNavigationBarHidden:NO];
[[self window] setRootViewController:navController];
But still the app autorotate in portrait mode when I rotate the device.
In iOS 6 I had not such behavior.
Try like this,
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return (UIInterfaceOrientationMaskLandscape);
}

presentViewController changes the orientation of the controller

I want to play a video from a view controller. When I present it, it is presented like it is a portrait orientation, so view turns. It only happens on iPhones,not the iPads.
There is a ViewController > MyItemsController > VideoController
When I close the VideoController, parent controller (MyItemsController) of the video controller is like:
Storyboard of the view controller is:
And the code is:
-(void)playMoviesForItems:(NSArray *)shopItems{
VideoPlayerViewController* moviePlayer = [self.storyboard instantiateViewControllerWithIdentifier:#"videoPlayerController"];
moviePlayer.modalPresentationStyle = UIModalPresentationCurrentContext;
moviePlayer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:moviePlayer animated:NO completion:nil];
}
I moved the code into app delegate :
-(void)playMoviesForItems:(NSArray *)shopItems{
VideoPlayerViewController* mp = [[self getStoryboard] instantiateViewControllerWithIdentifier:#"videoPlayerController"];
[mp playMoviesForItems:shopItems];
[self pauseBackgroundMusic];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:mp animated:YES completion:NULL];
}
This time, everything seem to be ok. Movie is playing, I can hear the sound, but cannot see the video. Why?
While the accepted answer was down voted since it does not answer the question, here's something that works on iOS9 :
The method that gets called when the ViewController is presented (modally) is preferredInterfaceOrientationForPresentation. This method must return an orientation.
You should check the presenter's orientation and return it as preferred:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation topOrientation = self.navigationController.visibleViewController.interfaceOrientation;
UIInterfaceOrientation presentingOrientation = self.presentingViewController.interfaceOrientation;
return presentingOrientation ? presentingOrientation : topOrientation ? topOrientation : UIInterfaceOrientationLandscapeLeft;
}
topOrientation contains the visible view controller's orientation, while the presentingOrientation is the orientation of the called to presentViewController:animated...
In general, I advise you to create a "base" UIViewController class, and inherit from it. This way all of your view controllers will benefit from this code.
I had this exactly same problem a few minutes ago.
What happened to me is that I was trying to present the new ViewController with a another ViewController which wasn't in the hierarchy, it only had it's view added as a subview of a third ViewController in the hierarchy. To fix the problem, I just made this last ViewController present the new one.
Example of what not to do:
UIViewController *secondController = [UIViewController alloc] init];
[rootViewController presentViewController:secondController animated:NO completion:nil];
UIViewController *controllerOutsideHierarchy = [UIViewController alloc] init];
[secondController.view addSubview:controllerOutsideHierarchy.view];
[controllerOutsideHierarchy presentViewController:thirdController animated:NO completion:nil];
Example of what should be done instead:
UIViewController *secondController = [UIViewController alloc] init];
[rootViewController presentViewController:secondController animated:NO completion:nil];
UIViewController *controllerOutsideHierarchy = [UIViewController alloc] init];
[secondController.view addSubview:controllerOutsideHierarchy.view];
[secondController presentViewController:thirdController animated:NO completion:nil];
Hope this helps!
Swift 4.1 version
To prevent auto rotation orientation you need to override shouldAutorotate variable
override var shouldAutorotate: Bool {
return false
}
To present view controller in landscape mode you need to override preferredInterfaceOrientationForPresentation variable
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeLeft// or .landscapeRight
}
You need to present view controller to get it work(It doesn't work for pushed view controller)
Make sure to add these two in the child view controller:
- (UIInterfaceOrientationMask) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationMaskLandscape);
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskLandscape);
}
Try this...
you must add the methods below , in your self.window.rootViewController 'class:
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
if your rootViewController is [UINavigationController class], command+n add a category of UINavigationController ,like my code below
#implementation UINavigationController (Rotation_For_iOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
and then ,go to the viewController.m which u want to be landscape or portrait mode,maybe for u is your VideoController !!!!!!
add methods below:
#pragma mark
#pragma mark ----- Orientation Control For iOS 6/7 -----
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight||toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
now i set my vc supported for landscape mode, last but not least,make sure your project deployment info select the orientation your want.

Resources