How to restrict rotation of view controller in ios 8? - ios

I want to disable the autorotation of iOS device for few view controllers.Like i have one few controller i want it to be displayed only in portrait mode.Where as others view controller in landscape mode.I have used following code but these delegate methods are never called?
#pragma mark Orientation handling
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}

I used following method to forcefully set portrait orientation only for some selected view and its work for me, may be it will be help you
1, Create one global flag
Create on Global flag in your AppDelegate Method So you can access it in any View controllers .
In your AppDelegate.h
#property (assign) BOOL flagOrientationAll;
In your AppDelegate.m
#synthesize flagOrientationAll;
Add following method in your AppDelegate.m
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if(flagOrientationAll == YES){
return UIInterfaceOrientationMaskAll; // All orientation support
} else {
return UIInterfaceOrientationMaskPortrait; // Set only one orientation you want
}
}
2, Add following code in ViewController .m for that you want to restrict rotation
// set flag "flagOrientationAll" to rotate only one view in your particular view
#import AppDelegate.h
-(void)viewWillAppear:(BOOL)animated
{
NSLog (#"webViewController -- viewWillAppear");
[super viewWillAppear:animated];
AppDelegate *delegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = YES;
}
-(void)viewWillDisappear:(BOOL)animated
{
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = NO;
}
Here my POST : How to set one of the screens in landscape mode in iphone?
If you get any trouble let me know!!

Related

Forced orientation change does not work sometimes

When a certain button is pressed in my app, the view should change orientation from portrait to
landscape. When the user comes back, the view controller should change back to portrait. But
sometimes the orientation doesn't change or the wrong view frame is used.
Here is my code
-(void)btnSignClicked:(CustomSignButton *)btn {
isSignButtonClicked = true;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_0) {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
else
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
}
selectedWaiverId = btn.customTag;
SignatureView *obj = [[SignatureView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) delegate:self]; // Most of time got size (568,320) but some time i got (320,568), Don't know why
[self.view addSubview:obj];
}
#pragma mark - SIGNATUREVIEW DELEGATE
-(void)removeSignatureView:(SignatureView *)signatureView {
isSignButtonClicked = false;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_0)
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"]; // Some time not changed the orientation are view remaining in landscape
}
else
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
}
[signatureView removeFromSuperview];
signatureView = nil;
}
#pragma mark
#pragma mark - Rotate screen
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if (isSignButtonClicked == true)
{
return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscape;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
- (BOOL)shouldAutorotate
{
return YES;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (isSignButtonClicked == true)
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
else
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
}
UPDATE
Sometimes viewWillTransitionToSize method is not called so I also integrate this notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
But sometimes this also does not work.
Add in AppDelegate.m file or any base controller file
#implementation UINavigationController (Orientation)
- (UIInterfaceOrientationMask) supportedInterfaceOrientations
{
return [(UIViewController*)[[self viewControllers] lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [(UIViewController*)[[self viewControllers] lastObject] preferredInterfaceOrientationForPresentation];
}
- (BOOL) shouldAutorotate
{
return [(UIViewController*)[[self viewControllers] lastObject] shouldAutorotate];
}
#end
Now put your ViewController object in UINavigationController object and push the view controller.
EX.
UINavigationController *obj=[[UINavigationController alloc] initWithRootViewController:_yourViewCtrlObj];
[self presentViewController:obj.....];
or
[self.navigationController pushViewController:obj animated:YES];
Set your desired orientation in all view controller.
If your app uses UINavigationViewController then create a custom class for UINAvigationController Like:
//CustomNavViewController.h
#import <UIKit/UIKit.h>
#interface CustomNavViewController : UINavigationController <UINavigationControllerDelegate>
#end
//CustomNavViewController.m
#import "CustomNavViewController.h"
#interface CustomNavViewController ()
#end
#implementation CustomNavViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
#end
And Now in your AppDelegate declare a property Like:
//AppDelegate.h
#property (assign, nonatomic) BOOL shouldRotate;
//AppDelegate.m
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.shouldRotate) {
return UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;
}
return UIInterfaceOrientationMaskPortrait;
}
Now you can call orientation methods to ViewController which required fix orientation Like:
//YourViewController.m
-(BOOL)shouldAutorotate{
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationLandscapeLeft;
}
Now here is the trick set AppDelegate shouldRotate property to true and false for desired orientation
if you are using Default Presentation for ViewController then
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:true];// Remember first update the value then present the ViewController
[self presentViewController:yourViewController animated:YES completion:nil];
Same as when you dismiss
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:false];
[self dismissViewControllerAnimated:YES completion:nil];
If you are using storyBoards then add CustomNavViewController directly on Identity Inspector Custom class section
And after that follow above steps. Hope it's working
When you say "When the user comes back, the view controller should change back to portrait", do you mean that the user is hitting the back button on a navigation controller? If so, I saw this issue before and posted a solution that worked for me in another SO post: A: Locking device orientation on a view fails when going back in NavBar. I remember the transition being rough but it worked.
I also wrote a blog post a while back that looks at some other situations around view controller orientation locking.
See this link, in particular, I think you should check the conditions of your view controllers, that they meet Apple recommendations
e.g. check supportedInterfaceOrientations method of the top-most full-screen view controller
Try adding all your rotation changing code inside this block
dispatch_async(dispatch_get_main_queue(),
{
//changing orientation code + isSignButtonClicked = true (or false)
});
You need not use shouldAutorotate and shouldAutorotateToInterfaceOrientation.
As for the view frames getting wrong, you need to use autolayout constraints for each and every view you are using in this viewController even if you are creating views programmativally

How can I lock orientation for a specific view an Objective-C iPhone app in iOS 8?

I'm just trying to set up my app so that only one view can be viewed in landscape mode.
I've tried just about everything from shouldAutorotate to supportedInterfaceOrientation to preferedInterfaceOrientationForPresentation, and setting [UIDevice currentDevice]'s orientation to portrait. I have Landscape enabled in Info.plist and the project's general section.
Firstly make your application portrait only in your info.plist
Create the following property in your AppDelegate class:
#property BOOL restrictRotation;
Then create the following method in your AppDelegate.m class:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if(self.restrictRotation)
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskAll;
}
Create the following method in your ViewController and call it right before you want to permit landscape orientation. (Call it with true first in your viewDidLoad method to make sure rotation is restricted)
-(void) restrictRotation:(BOOL) restriction
{
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
like this:
[self restrictRotation:NO];
and after you are done with your landscape view and its dismissed, call this immediately:
[self restrictRotation:YES];
Hope this answers your question.
also change orientation after locking it:
-(void)forceOrientation:(UIInterfaceOrientation)orientation{
[[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:orientation]forKey:#"orientation"];
}
set in app delegate
For iOS 6 and above to clear the warning in AppDelegate while using Gurtej Singh answer you can replace the AppDelegate code with :
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(tvos)
{
if(self.restrictRotation)
return UIInterfaceOrientationMaskPortrait;
else
return UIInterfaceOrientationMaskAll;
}
In your app delegate you could do this:
// Used to show a video in full screen
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int
{
if let presentedViewController = self.window?.rootViewController?.presentedViewController
{
if !presentedViewController.isBeingDismissed() && presentedViewController is MyLandscapeModeViewController // insert your view controller class name here
{
// specify what kind of Orientation you want
return Int(UIInterfaceOrientationMask.AllButUpsideDown.rawValue)
}
}
// show every other View Controller in portrait
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

Force the iOS device to change orientation

First of all, I would like to apologize for asking the same question again which has been asked in this forum many times. But, my problem is that I've tried all the suggested solutions but still I haven't got a solution to my problem.
I have a ViewControllerA in Potrait mode and ViewControllerB in landscape mode. When the device changes from potrait to landscape, i can see ViewControllerB opening in landscape mode, but when the device is rotated back to potrait mode, ViewControllerA is displayed but still in landscape mode. Could anybody help me understand how can I display it back in potrait mode?
I have tried following things but nothing worked for me:
Added following code in ViewControllerA in viewWillAppear:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
Have also added following functions in this view controller:
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
Hope this helps you by using supportedInterfaceOrientationsForWindow
Appdelegate.h
#property () BOOL restrictRotation;
in Appdelegate.m
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
//restrictRotation is BOOL value
if(self.restrictRotation)//set the bool value to view controller which you want to load in landscape
return UIInterfaceOrientationMaskLandscape;
else
return UIInterfaceOrientationMaskAll;
}
//call this where you need
requiredViewController.m
-(void) restrictRotation:(BOOL) restriction
{
appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
appDelegate.restrictRotation = restriction;
}
//In ViewdidLoad()
- (void)viewDidLoad
{
[super viewDidLoad];
[self restrictRotation:YES];//Set YES if required in Landscape mode
}
Please try
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:#"orientation"];
Use below code
-(void) viewDidAppear:(BOOL)animated
{
[UIViewController attemptRotationToDeviceOrientation];
[super viewDidAppear:animated];
}
& also in viewWIllAppear write
[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:#"orientation"]

IOS7/IOS8 Allow only portrait in view controller

I am building an app for iPhone that will have only 1 landscape view, and so i want to block landscape for all other, i have tried this:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
But it stills rotates
I will suggest to just make your app for portrait mode and then whenever you need the landscape mode then allow landscape mode.
First, as previously suggested click on -> Project name -> General -> Deployment Info -> Only select Portrait for Device Orientation.
Second, in your AppDelegate.h add this property..
#property (nonatomic) BOOL fullScreenVideoIsPlaying;
Then, on your AppDelegate.m I will add this function..
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
if (self.fullScreenVideoIsPlaying == YES) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else {
return UIInterfaceOrientationMaskPortrait;
}
}
After doing this, in the view controller that you need landscape create a function or just add this code to your viewWillAppear method is depending how you want to accomplish this..
((AppDelegate *)[[UIApplication sharedApplication] delegate]).fullScreenVideoIsPlaying = YES;
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
Then for setting back to portrait mode you do this..
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.fullScreenVideoIsPlaying = NO;
[self supportedInterfaceOrientations];
[self shouldAutorotate:UIInterfaceOrientationPortrait];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
You might need these functions for iOS 8..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (BOOL)shouldAutorotate:(UIInterfaceOrientation)interfaceOrientation{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
I hope it helps.. :)
Click project and select Orientation settings from there.

iOS 7 Interface Orientation

I have an app that is always showed in portrait mode.
But in somewhere i have a media gallery that must support landscape.
The supported orientation by default in the project is portrait. Because of that the gallery is only showed in portrait mode.
If i change the project setting to show in portrait and landscape the gallery works fine but i can't control the other viewControllers to show only in portrait.
I tried several methods like shouldAutoRotate but no one worked.
Any ideia how to solve?
Regards
EDIT:
Solved :)
First i configured the project to support all orientation.
Then i added this method to the AppDelegate.m:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
}
After this what i did was to block orientation in each view controller, less the one i want to have orientation in landscape and portrait.
Code to block orientation (iOS 7):
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}
Thanks to everyone that answered me :)
In my app for iPhone its only support the portrait view only, but as per requirement need to support landscape view only for on view, at that time I use following way and its help me :
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([UICommonUtils isiPad]){
return UIInterfaceOrientationMaskAll;
}else if(flagOrientationAll == YES){
return UIInterfaceOrientationMaskAll;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
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;
}
see this post also: How to set one of the screens in landscape mode in iphone?
You have to make another class in the same view Controller where you are presenting your media.
In that you can specify your orientation where it will support only landscape orientation only when you will present your media.
I am giving you an example of my app which supports only in landscape mode but as I took Image picker and it supports only in portrait mode so I changed the orientation for only that view.
#pragma mark - Image PICKER
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait ;
}
#end
Then when I used ImagePicker I used object of the class that i made.
So I define like below.
UIImagePickerController* picker = [[NonRotatingUIImagePickerController alloc] init];
So For Image Picker It showed only in portrait mode.
You just need to change Landscape instead of portrait if you want only Landscape Orientation for your particular view where you want to change it.
Hope this helps you.

Resources