I want to set device orientation to landscape mode programmatically to particular viewcontroller, its working well if I use with UIAlertController, with YES/NO option, but if I directly write the same code on button click. its not working.
working code with UIAlertController,
UIAlertController * alert=[UIAlertController
alertControllerWithTitle:APP_NAME message:#"Please Select Video Orientation."preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Landscape Mode"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
[self.navigationController pushViewController:mySecondViewController animated:NO];
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"Portrait Mode"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
[self.navigationController pushViewController:mySecondViewController animated:NO];
}];
[alert addAction:yesButton];
[alert addAction:noButton];
[self presentViewController:alert animated:YES completion:nil];
The above code is working well, but i want to force next controller in landscape mode without asking with Alert, so directly write the code on button click like this,
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
[self.navigationController pushViewController:mySecondViewController animated:NO];
but this same code is not working well. it will open the mySecondViewController in portrait first and manually we have to tilt phone once then it will move into landscape.
I tried lot of option but no luck. Testing on iPhone5 and iPhone6 with iOS 10.1
Update: adding mySecondViewController code,
This is second view controller code,
-(void)viewWillAppear:(BOOL)animated{
self.navigationController.navigationBar.hidden = NO;
}
- (void)viewDidAppear:(BOOL)animated {
// [super viewDidAppear:animated];
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft|UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
-(BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Try this for force the view to launch in landscape mode in swift :
Use this code in viewWillAppear
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(Int(value), forKey: "orientation")
and
override func shouldAutorotate() -> Bool {
return true
}
This is code for set orientation, but if you want for specific VC try this code in that VC class
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:#"orientation"];
Related
I need to fix orientation portrait or landscapeLeft like Youtube's full screen.
When a user click button, it was changed portrait or landscapeLeft.
and was fixed.
The user can control only by button.
accept Device orientation Portrait, Landscape Left in General
It's my code
AppDelegate
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(restrictRotation)
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskLandscapeLeft;
}
ViewController
-(void) restrictRotation:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate->restrictRotation = restriction;
}
- (IBAction)rotateOrientationAction:(id)sender
{
[self restrictRotation:NO];
if(isPortrait){
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationLandscapeLeft) forKey:#"orientation"];
self.myNewScrollViewHeight.constant = self.view.frame.size.height - self.naviBar.frame.size.height - self.horizMenu.frame.size.height;
self.portraitMenuView.hidden = YES;
}else{
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationPortrait) forKey:#"orientation"];
self.myNewScrollViewHeight.constant = self.view.frame.size.height * 0.5;
self.portraitMenuView.hidden = NO;
}
isPortrait = !isPortrait;
[self restrictRotation:YES];
}
If I click the button, it was changed landscapeLeft but not changed portrait again.
Thank you
Your condition is not satisfied for restrictRotation, please check below code to desire result.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
isPortrait = YES;
}
-(void) restrictRotation:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
- (IBAction)rotateOrientationAction:(id)sender
{
if (isPortrait) {
[self restrictRotation:NO];
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationLandscapeLeft) forKey:#"orientation"];
} else {
[self restrictRotation:YES];
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationPortrait) forKey:#"orientation"];
}
isPortrait = !isPortrait;
}
Update :
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
isPortrait = YES;
}
- (IBAction)rotateOrientationAction:(id)sender
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = NO;
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationPortrait) forKey:#"orientation"];
if (isPortrait)
{
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationLandscapeLeft) forKey:#"orientation"];
}
else
{
[[UIDevice currentDevice] setValue:#(UIInterfaceOrientationPortrait) forKey:#"orientation"];
}
isPortrait = !isPortrait;
}
I want to change the orientation of specific ViewController in Xcode.
I make a,b,cViewController and change the orientation only cViewController to LandscapeRight. (a and b's orientation are Portrait)
But if I change the orientation on cViewController and move ViewController from c to b, b's orientation is also changed to LandscapeRight.
(screen transition is push)
code:
a and bViewController's DidLoad
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
cViewController's DidLoad
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
How can I change the orientation only cViewController?
step-1
create the one bool property in your appdelegate like , this
#property () BOOL restrictRotation;
and call the function
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
return UIInterfaceOrientationMaskLandscape ;
else
return UIInterfaceOrientationMaskPortrait;
}
step-2
and import the appdelegate #import "AppDelegate.h" in C VC
on your C VC View Will appear, call like
-(void)viewWillAppear:(BOOL)animated{
// for rotate the VC to Landscape
[self restrictRotationwithNew:YES];
}
(void)viewWillDisappear:(BOOL)animated{
// rotate the VC to Portait
[self restrictRotationwithNew:NO];
[super viewWillDisappear:animated];
}
-(void) restrictRotationwithNew:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
Choice 2
on your C VC check the Orientation using the delegate function of UIDeviceOrientationDidChangeNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
- (void)orientationChanged:(NSNotification *)notification{
[self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
switch (deviceOrientation) {
case UIDeviceOrientationPortrait:
NSLog(#"orientationPortrait");
;
break;
case UIDeviceOrientationPortraitUpsideDown:
NSLog(#"UIDeviceOrientationPortraitUpsideDown");
break;
case UIDeviceOrientationLandscapeLeft:
NSLog(#"OrientationLandscapeLeft");
break;
case UIDeviceOrientationLandscapeRight:
NSLog(#"OrientationLandscapeRight");
break;
default:
break;
}
}
It is an superclass file name Apporientationviewcontroller.h/m. And i am calling this super class in all other subclasses. So that if "isPortraitModeONN" is "ON"
then all the screen should work only in portrait mode. if user try to changes the device to landscape it should not rotate. it should be always in portrait mode if switch is "ON".. In my case while laughing the app it is in portrait mode. but if i rotate the screen it is changing towards landscape. but it should not change its orientation until turning OFF the switch in settings..
if(isPortraitModeONN)
{
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
else
{
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft){
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
{
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];
}
else{
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
}
This code works for me somewhat..
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator: (id<UIViewControllerTransitionCoordinator>)coordinator
{
///if isPortraitMode On then force the orientation to portrait if it's other than Portrait
///else force the orientation to landscape
if (isPortraitModeONN)
{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
// do whatever
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsLandscape(orientation)) {
///App is rotating to landscape, force it to portrait
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
}];
}
else{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
// do whatever
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientation)) {
///App is rotating to portrait, force it to landscape
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
}];
}
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
You can do like this-
Add - #property () BOOL isPortraitModeONN; in AppDelegate.h class.
Now code this in AppDelegate.m -
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.isPortraitModeONN=YES;
return YES;
}
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.isPortraitModeONN)
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskLandscape;
}
Now Add IBAction of UIButton for changing orientation in Apporientationviewcontroller.m--
- (IBAction)changeOrientation:(id)sender {
if (allowedToRotate) {
allowedToRotate=NO;
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.isPortraitModeONN = NO;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}else{
allowedToRotate=YES;
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.isPortraitModeONN = YES;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
}
define in Apporientationviewcontroller.m BOOL allowedToRotate; default value is YES;
Goto Target -> Deployment info -> set device Orientation to portrait only
As par your question if you want to do this by tapping on button
Please try this code i am not sure about this it works on your project but it works for my dummy project
please try it
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:#"orientation"];
change the device orientation for both buttons
You code should be like this,
AppDelegate.h
#property () BOOL restrictRotation;
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
AppDelegate.m
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
return UIInterfaceOrientationMaskLandscape; //you can change upsidedown etc
else
return UIInterfaceOrientationMaskPortrait; // you can change landscape right or left only
//this should be your initial app orientation because by default value of bool is false
}
SettingsViewController (from where you want to change whole app orientations)
-(void) restrictRotation:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
[appDelegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
}
don't forget to import appdelegate.h ;)
And finally from your switch for changing orientation,
[self restrictRotation:YES]; // or NO
You can manipulate supportedInterfaceOrientationsForWindow as per requirement like you can set property as int instead of bool and can set multiple orientation for different int value.
hope this will help :)
I have a bit of a strange situation. I have a photo app that automatically sets the app orientation based upon the dimensions of the image loaded. I use the following code.
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (BOOL) shouldAutorotate {
return NO;
}
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return NO;
}
- (IBAction)setRotation {
if(imageOriginal.size.height > imageOriginal.size.width){
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}else {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
}
The problem is that lets say I load a portrait image into the app the UIImagePicker is in portrait mode. I now select a Landscape image and select the UIImagePicker again, instead of the picker now being in landscape mode it jumps back to portrait and looks pretty ugly.
Is there a better way to set the device orientation based upon the image or fix the problem above?
Found the solution needed to change the following code to make sure the UIImagePicker was in context.
- (IBAction)loadImage:(id)sender {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
-- > imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
//imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentViewController:imagePicker animated:NO completion:nil];
}
My app is a portrait only. I need to present a UIViewController in Landscape mode(Reason for that is I am using Core-Plot sdk for drawing graphs on that viewcontroller, so it needs to be in landscape mode).
I tried the following methods and it work fine. But the issue is, when I dismiss the landscape viewcontroller, app cannot force to portrait mode.
http://www.sebastianborggrewe.de/only-make-one-single-view-controller-rotate/
http://b2cloud.com.au/tutorial/forcing-uiviewcontroller-orientation/
How can I force the app to become portrait only mode after dismiss the landscape viewcontroller?
This is How I presenting the landscape view controller and dismissing it.
LineChartViewController *obj = [[LineChartViewController alloc]initWithNibName:#"LineChartViewController" bundle:nil];
[self.navigationController presentViewController:obj animated:YES completion:nil];
- (IBAction)btnDonePressed:(id)sender{
[self dismissViewControllerAnimated:NO completion:nil];
}
XIB of the LineChartViewController is in landscape mode.
In simple words, My app is portrait only, and I wanted to show CorePlot hostView in landscape mode.
Actually I could solve the issue by rotating the CorePlot hostView. The solution isn't the perfect for the the question described, but I'd like to put my solution here, since it solved my problem
self.hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:self.viewGraphBack.bounds];
self.hostView.allowPinchScaling = YES;
[self.viewGraphBack addSubview:self.hostView];
CGAffineTransform transform =
CGAffineTransformMakeRotation(DegreesToRadians(90));
viewGraphBack.transform = transform;
viewGraphBack.frame = CGRectMake(-285, 0, 568, 320);
[self.view addSubview:viewGraphBack];
This kind of workaround works for me (temporary pushing fake model view controller), called after other view controller which introduces new orientation is demised:
- (void)doAWorkaroudnOnUnwantedRotation {
// check if is workaround nesesery:
if (UIInterfaceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
double delayInSeconds = 0.7;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
UIViewController *fake = [[[UIViewController alloc] init] autorelease];
UIViewController *rootController = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootController presentModalViewController: fake animated: NO];
[fake dismissModalViewControllerAnimated: NO];
});
}
}
If Parent viewcontroller in UIInterfaceOrientationPortrait mode & current viewcontroller should be in UIInterfaceOrientationLandscapeLeft or UIInterfaceOrientationLandscapeRight in that case you may use device orientation changing delegate & a few codes in viewdidload
In ViewDidLoad
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
& implement shouldAutorotateToInterfaceOrientation delegate in ViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) return YES;
return NO;
}
Like this. Assure that landscape mode must be checked in from target settings.
Write this category in your project
#import "UINavigationController+ZCNavigationController.h"
#implementation UINavigationController (ZCNavigationController)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
And in your viewcontroller where you need Landscape
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}