I have an app in which the root controller is a UINavigationController. Push one button, and it pushes another view controller. Push yet another and it starts an AVCaptureSession with Overlay. I want THAT view, and that view ONLY to be Landscape, and not portrait. I have looked at a ton of different tutorials, and nothing is working.
The closest I have gotten is:
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
in the viewDidAppear. However, there are some issues. One, it immediately goes right back to Portrait. Two, the other views are still all able to be portrait and landscape and I don't want that. I need help, please.
In my app delegate, I use this code and make sure only portrait mode is selected:
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([self.window.rootViewController.presentedViewController isKindOfClass:[SecondViewController class]])
{
SecondViewController *secondController = (SecondViewController *) self.window.rootViewController.presentedViewController;
if (secondController.isPresented)
{
return UIInterfaceOrientationMaskLandscape;
}
else return UIInterfaceOrientationMaskPortrait;
}
else return UIInterfaceOrientationMaskPortrait;
}
yes you can make particular viewController as a landscape by placing bellow method in your appDelegate.
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskAll;
}
then take one bool property in your appDelegate
#property (nonatomic) BOOL restrictRotation;
and then in view controller where you want to change orientation create appDelegate shared instance and allow restriction to change like bellow method
-(void) restrictRotation:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
now call this method from your view controller and change orientation as you want.
[self restrictRotation:NO];
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
and the most important thing is to change orientation to portrait when your view will be disappear otherwise all the other viewController also become in a landscape mode.
-(void)viewWillDisappear:(BOOL)animated
{
NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
[self restrictRotation:YES];
}
I hope this will help you.
Related
I know that this subject has been asked before, but I went over all solutions and none solved the case I'm having.
My app is all in portrait format, only one view controller in landscape format.
I added to all view controllers the following code to force Portrait Orientation regardless the device orientation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate{
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
-(void)ViewDidLoad()
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
}
If the device is set in portrait mode the viewController opens correctly, but if the device is set landscape mode before opening the app, then the app launches the splash screen in landscape and opens the view controller in landscape with part of the view clipped, then it rotates it to portrait mode, and keeps part of the screen clipped, as shown in the picture.
in the app delegate:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
And in the appDelegate also, just before adding the view controller to the navigation controller I added the following:
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:#"orientation"];
This seems to be a new thing since iOS 11. I fixed it by allowing autorotate but only supporting portrait.
(BOOL)shouldAutorotate{
return YES;
}
(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
I'm having the same problem. But I fix it by rotate the device orientation programmatically.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if UIDevice.current.orientation != .portrait {
UIDevice.current.setValue(UIDeviceOrientation.portrait.rawValue, forKey: "orientation")
}
return .portrait
}
ok here what I did and it finally working well, hope it can help someone:
in appDelegate I'm putting the following:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
To introduce the main view I'm using the following from appDelegate:
self.navigationController = [[UINavigationControllerSub alloc] initWithRootViewController:libraryVC];
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
portraitSize = CGSizeMake(navigationController.view.frame.size.width, navigationController.view.frame.size.height);
[self.window setRootViewController:navigationController];
In the main view which I launched from the app delegate and I need it to be only portrait I'm doing the following:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:#"orientation"];
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:NO];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
}
When I want to launch a view where I need it to be landscape I use the following just before launching:
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:YES];
[UIApplication sharedApplication].statusBarOrientation = UIDeviceOrientationLandscapeLeft;
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:#"orientation"];
You need to set your project as Portrait only to make sure the app launches in portrait regardless of the device's orientation.
Also, make sure you have supportedInterfaceOrientationsForWindow implemented on your AppDelegate and that it returns UIInterfaceOrientationMaskAll or whatever mask makes sense for your project.
With all that, you'll have the app launching with portrait and control over allowed orientations per view controller, with the implementation you already have.
I'm making the app with UISplitViewController but the it require show only the MasterViewController on Portrait mode in Ipad (work same as the Portrait mode on iPhone). In the landscape mode, it works normally.
Please give me some idea to make it. Thanks in advance.
Put this in viewWillAppear
NSNumber *value = [NSNumber numberWithInt: UIInterfaceOrientationMaskPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
plz use this code in app delegate class
-(id)getTopViewController{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
if (![topController isKindOfClass:[NSNull class]]) {
return topController;
}
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
UIViewController *viewOb = [self getTopViewController];
if ([viewOb isKindOfClass:[MasterViewController class]]) {
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAll;
}
Plese use this code it will be help you out
- (BOOL)shouldAutorotate{
//disable rotation
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
//allow only portrait interface orientation
return UIInterfaceOrientationMaskPortrait;
}
Sir,
I am working on the mapview module which landscape is the only orientation allowed but others for portrait only. When it comes to running on device ios 7 and 8 , the view controller is still presented as portrait orientation unless I have to manually turn the device to landscape . Would you please tell me what other steps to do ?
The below is my code
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic) BOOL isTaskPoint;
#end
AppDelegate.m
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) return YES;
return NO;
}
PreviousController.m
MapViewController * sliderVC = [[MapViewController alloc] init ];
AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
appDelegate.isTaskPoint = TRUE;
sliderVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:sliderVC animated:NO completion:nil];
sliderVC.view.backgroundColor = [UIColor clearColor];
// MapSwift maps =
MapViewController.h
- (void)bannerTapped:(UIGestureRecognizer *)gestureRecognizer {
AppDelegate *appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
appDelegate.isTaskPoint = FALSE;
[self dismissViewControllerAnimated: NO completion:nil];
}
MapViewController
- (BOOL) shouldAutorotate {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight|| interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
There is one trick that really works.
You can access the status bar and set its orientation. That becomes active next time a view is displayed modally.
However, right after displaying modally you can remove the modally displayed veiw controller. When you do that within the same method, then the user would not noticing anyhing.
Now the device has the desired orientation. You can now safely push the view controller that you want to be in another orientation.
Do not forget to rotate it back, when returning from that view controller!
See the answer to this question. It comes with some code sniplets. Force controllers to Change their orientation in Either Portrait or Landscape
If you want to disable or enable specific orientation in some view controller then this might be helpful to you.
And if you want to open some view in specific orientation then use this in viewDidLoad
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
I am working on an application that has about 12 views. I want some to be portrait only and others to be landscape.
How would I go about locking some view's orientation to portrait and others to landscape?
I tried the code below from a previous example, but It does not lock the orientation.
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationLandscapeLeft]
forKey:#"orientation"];
After almost 24 hours of trying I finally fixed the problem. For one "ShouldAutoRotate" never gets called. And thats all I could find everywhere "Just add shouldAutoRotate"... Didnt work. Also i am not sure why people are down voting my question.
What work for me was the add the method below to my Appdelegate.m file.
- (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;
}
Then add the method below to the viewcontroller.m file I want to be locked to landscape.
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
You have to implement supportedInterfaceOrientation and shouldAutorotate in your ViewController.
Apple Documentation
my project have UITabbar, UınavigationBar and UIViewContoller.
-UITabbar
—UINavigationController
—UIViewController
Question: how can i do landscape disable just one viewController? i want to only portrait view but for just one view.
disable autorotate on a single UIViewController in iOS6
Add this to your app delegate
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if ([[window.rootViewController presentedViewController] isKindOfClass:[YourViewController class]])
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskAllButUpsideDown;
}
EDIT 2
I recently found out about this, and it has been working perfectly for me. Add this code to your view controller
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And in your viewWillAppear add
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
///Disable orientation changes
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}