How to Autorotate subview in iOS6? - ios

In iOS6, autorotate is different from previous version, because it should be worked with UINavigation. I have a View_A with UINavigation bar and it pushViewController:View_B and View_B pushViewController:C. So View_A, View_B and View_C all can autorotate. My question is if in View_C I use addsubview to add View_D as subview, View_D don't autorotate. I don't know how to autorotate subview in iOS 6. Did someone have the same question with me?

Try this code:
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation==UIInterfaceOrientationPortrait) {
// do the UI changes
}
if(orientation==UIInterfaceOrientationLandscape){
// do UI changes
}
return YES;
}

Related

How to force view to enter landscape in iOS?

I've see a dozen of possible related questions on SO, but no one seems duplicated:
how to force view to rotate to landscape in viewdidload?
force landscape ios 7
IOS - How to force the view to landscape
Force landscape for one view controller ios
iOS - Force Landscape Orientation
How to make app fully working correctly for autorotation in iOS 6?
My app is a tab-based application.
Currently when entering certain views, I can rotate my phone to landscape to let my view enter landscape.
Main Code:
// In app delegate
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (_allowRotation == YES) {
return UIInterfaceOrientationMaskLandscape;
}
else {
return UIInterfaceOrientationMaskPortrait;
}
}
In views that I want to be landscape, I set allowRotation to YES.
But I want to force views to enter landscape.
In other word, when entering certain views, it automatically enters landscape, no need to rotate phone. Even user locks the screen as portrait. How to achieve this?
I'm using iOS 10.
You have to override the onDidLoad or onDidAppear of the specific view that you want to move it to landscape, for example i added it to viewWillAppear and Disappear:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
self.navigationController.navigationBarHidden = NO;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
-(void)viewWillDisappear:(BOOL)animated {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
[super viewWillDisappear:animated];
}
so we the view appear the application move to landscape and when the move disappear it come again to portrait. and for the appDelegate you have to add this:
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
if ([navigationController.viewControllers.lastObject isKindOfClass:[OpencvViewController class]])
{
return UIInterfaceOrientationMaskLandscape;
}
else
return UIInterfaceOrientationMaskPortrait;
}
Call [UIViewController attemptRotationToDeviceOrientation] when you need rotate orientation
Yours code will be something like that:
appDelegate.allowRotation = YES;
[UIViewController attemptRotationToDeviceOrientation];
Use below code in the specific view controller that you want to rotate in to landscape mode.
-(void)viewDidLayoutSubviews
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
You need to use
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
for container view controller in window.rootViewController hierarchy or while presenting view controller over another one.
This enforces you controller to appear in landscape orientation.
The simplest example is assigning rootViewController to the main window.
If you use UIInterfaceOrientationMaskLandscape in your view controller it appears in landscape from the very beginning.
If you try to pack your controller into navigation controller you'll need to subclass the latter to define UIInterfaceOrientationMaskLandscape in it because it is the container for your own view controller.
The same is valid for other containers (e.g. tabBarController or your own containers) which have parent-child link.
While presenting view controller you have also another method to fix orientation:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation

Force Landscape View on one UIViewController only

I have an app that is portait mode only. I only have one View Controller that I need to force into landscape mode (A customer signature view) so there is more room for the customer to sign.
How can I force one ViewController to appear in landscape mode. Leaving the rest in portrait?
I have tried setting the app's General Deployment info to Portrait, Landscape Left
And then using this code on the Signature View
- (BOOL)shouldAutorotate {
return YES;
}
and returning NO on all other view controllers. But that didn't seem to work.
I also included
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Is this possible?
Try this code in the Signature View Controller
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeLeft] forKey:#"orientation"];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:#"orientation"];
}
You're just missing the following code below, if your UIViewController is a rootcontroller of a navigationcontroller you need to put the code in the navigationcontroller. Hope this helps, good luck.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Following is the the way its working for me:-
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
and
- (BOOL)shouldAutorotate {
return NO;
}
Another way is to define orientation in prepareForSegue and fixed orientation of the required VC and set shouldAutorotate to NO in that VC.
Let me know if mentioned code doesn't work for you.

Rotate to Landscape for a view - iOS

I have used the below code to force the view to landscape.
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationLandscapeLeft);
Is apple approve this for orientation or have any chance to reject my app.Please provide your solution.
I do not think so. Apple documentation state that orientation is read-only property.
To force landscape into ViewController, you can do:
- (NSUInteger)supportedInterfaceOrientations;
{
return UIInterfaceOrientationMaskLandscape;
}
To present the ViewController in a specified orientation mode:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
{
return UIInterfaceOrientationLandscapeLeft;
}
For all these to happen, the plist of the project must support the orientation and:
- (BOOL)shouldAutorotate;
{
return YES;
}
All these is assuming the view controller is not presented under same UINavigationController. For such case, you should refer to this discussion on work around of forcing rotation on UINavigationController: UINavigationController Force Rotate
For views that you want to force into landscape, you can always use transform:
self.view.transform = CGAffineTransformMakeRotation(M_PI/2.0);

iOS 6: how to force change orientation when pushing view controller into the navigation controller stack [duplicate]

This question already has answers here:
In iOS6, trouble forcing ViewController to certain interfaceOrientation when pushed on stack
(3 answers)
Closed 9 years ago.
I think this question should've been asked a million times by now, but I still can't find an answer to this.
Here's my hierarchy: UINavigationController -> UIViewController 1 ->(push)-> UIViewController 2
UINavigationController: supports all possible orientation
UIViewController 1: supports only portrait
UIViewController 2: supports only landscape
How can I lock UIViewController 1 into portrait only and at the same time lock UIViewController 2 into landscape only? Is it even possible? So far what I see is that UIViewController 2 always takes the orientation of UIViewController 1.
Note, that this is for iOS 6 only.
Thanks!
I am also find the same problem.i have found that shouldAutorotate function not call every time so i change orientation programmatic
first import this
#import <objc/message.h>
then
-(void)viewDidAppear:(BOOL)animated
{
if(UIDeviceOrientationIsPortrait(self.interfaceOrientation)){
if ([[UIDevice currentDevice] respondsToSelector:#selector(setOrientation:)])
{
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationLandscapeLeft );
}
}
}
hope this help you.
Add new Objective-C class (subclass of UINavigationController) and add the following code to the .m files
-(NSUInteger)supportedInterfaceOrientations
{
NSLog(#"supportedInterfaceOrientations = %d ", [self.topViewController supportedInterfaceOrientations]);
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
After you added the new classes go to your ViewController classes and make the following changes
- (BOOL)shouldAutorotate // iOS 6 autorotation fix
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations // iOS 6 autorotation fix
{
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation // iOS 6 autorotation fix
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
In the shouldAutorotate , shouldAutorotateToInterfaceOrientation: return YES if you want the ViewController to be supporting Multiple orientation else return NO , also in houldAutorotateToInterfaceOrientation: method pass the Orintation you want for that specific ViewController , Repeat the same for all the view controllers .
Reason of doing this:-
1:Although you can change the preferredInterfaceOrientationForPresentation: of any viewController to a specific orientation but since you are using the UINavigationController you also need to override the supportedInterfaceOrientations for your UINavigationController
2:In order the override the supportedInterfaceOrientations for UINavigationController we have subclassed UINavigationController and modified the method related to the UINavigation Orientation.
Hope it will help you !
Make the app support only portrait mode and add the following line to the initWithNibName of UIViewController 2
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);

How do I force a specific UIInterfaceOrientation on an individual view in a UINavigationController?

Okay, so here's the situation:
I have an app in which I only want ONE specific view in a UINavigationController to have a landscape orientation. This view is a UIImageView that I'm capturing a signature on (THAT part works awesome). So, like this:
previous view --> signature view --> next view
(portrait) (landscape) (portrait)
I can't seem to find a good way to force the device orientation to landscape on that signature screen. It'll never make sense to have a portrait orientation on the signature view because there's really not adequate room for signing in that screen width.
So, any bright ideas on how to accomplish this? I've considered possibly doing the signature view modally, thus breaking out of the navigation controller. Thoughts?
You can try to force Device to rotate to necessary orientation - but you need to handle it manually (in addition to overriding UIViewController orientation handling methods).
To rotate device you can use next methods:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
But in it may not work in all situations...
Also available undocumented approach:
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:")
withObject:(__bridge id)((void*)UIInterfaceOrientationLandscapeLeft)];
Just override this UIViewController method to only return true for landscape like so and the iphone will be forced to rotate to that device orientation, since it has no other option.
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Unfortunately, all root UIViewControllers inside of a Navigation Controller must support any of their child orientations. This means that the first view controller in your setup must support landscape, otherwise the child will only support portrait.
The best way to implement what you are looking for is to create a UIViewController that displays its content view on a rotated transform, and just default all UIViewControllers in that stack to portrait.
I think you can embed this view inside a view controller and overwrite the ShouldRotateToInterfaceOrientation method.
Good luck!
To use a View in only landscape, I have the following in the ViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
This might be what your looking for.
// Rotates the view.
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14159/2);
self.view.transform = transform;
// Repositions and resizes the view.
CGRect contentRect = CGRectMake(-80, 80, 480, 320);
self.view.bounds = contentRect;
from http://www.iphonedevsdk.com/forum/iphone-sdk-development/1394-landscape-uiviewcontroller-uiview-rotation.html
I have an app that has landscape only views that even starts in landscape. This was working fine in iOS 5.x but stopped working in iOS 6.x
After trying many many things, some more questionable than others, I found a solution that to me is clear and predictable.
I did several things.
-- I kept the views in landscape mode in IB.
-- I checked both landscape modes in the project settings - there a four icons there to control it
-- Orientation mgmt has changed in iOS 6.x. I had to overwrite a few methods to support changing to landscape
this method is for iOS 5.x
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations.
return (interfaceOrientation & UIInterfaceOrientationMaskLandscape);
}
these 2 methods are for iOS 6.x
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger supportedOrientations = UIInterfaceOrientationMaskLandscape;
return supportedOrientations;
}
- (BOOL)shouldAutorotate
{
return YES;
}
-- But the key was to change the logic in the AppDelegate. Original code I had there was adding a subview (controller.view) to the window. This stopped working in iOS 6.x - I changed the call to window.setRootController. That was the final step that sealed it - it would not work without making this final change
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//[self.window addSubview:viewController.view];
[self.window setRootViewController:viewController];
[self.window makeKeyAndVisible];
return YES;
}
The UINavigationController overrides the contain UIViewController orientation settings, so you have to create a custom subclass of UINavigationController with the following for 5.1:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[self topViewController] isKindOfClass:[SigCaptureViewController class]]) {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
} else {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
For 6.0 and above you need:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
if ([[self topViewController] isKindOfClass:[EXTRASigCaptureViewController class]]) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
What I haven't figured out is how to make the force the UINavigationController to rotate. calling [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO] causes the status bar to rotate but doesn't cause the view to rotate.

Resources