I have two viewController, So I want the first viewController can rotate all side and second viewController can rotate left side only. And this is my code in second viewController.
Thank you very much.
-(NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
If you are using navigationController,
Create a category like this,
#interface UINavigationController (Rotation_IOS6)
#end
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
if([self.visibleViewController isMemberOfClass:NSClassFromString(#"SecondViewController")])
{
return UIInterfaceOrientationMaskLandscapeLeft
}
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [[self topViewController] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
if([self.visibleViewController isMemberOfClass:NSClassFromString(#"SecondViewController")])
{
return UIInterfaceOrientationMaskLandscapeLeft
}
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
- (BOOL)shouldRotateToOrientation:(UIDeviceOrientation)orientation {
if (orientation == UIDeviceOrientationLandscapeLeft) {
return NO;
}
else if (orientation == UIDeviceOrientationLandscapeRight) {
return NO;
}
else if (orientation == UIDeviceOrientationPortrait) {
return NO;
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
return YES;
}
}
//Use this method to check which orientation going to execute and you can return no if you
//want to stop orientation and if you return yes then orientation execute
First you need to add the category of NavigationController
Declare that bool in AppDelegate to used in all over projcet.
Declare property AppDelegate.h
#property BOOL * islandscape;
AppDelegate.m file
#synthesize islandscape;
.h file
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#interface UINavigationController (orientation1)
#end
.M File
#import "UINavigationController+orientation1.h"
#implementation UINavigationController (orientation1)
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
if (delegate.islandscape)
{
// for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
return UIInterfaceOrientationMaskLandscape;
}
return UIInterfaceOrientationMaskPortrait;
}
#end
and then used that bool varible in SeconViewController.
delegate.islandscape=Yes;
Related
I'm creating a ebook application in which i have only given all orientation's to two of the ViewControllers.
i was abel to successfully set the orientation to the two ViewControllers and perform the Rotation for the first time.but later when i load the view controller with new book the rotation is not working properly.
i used the methods:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
//code for landscape
}
else{
//code for protrait.
}
}
- (BOOL)shouldAutorotate{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations{
return (UIInterfaceOrientationMaskAll);
}
Try to handle rotation on your UINavigationControllers, your exact code on a UINavigationController subclass is correct. And make sure your UIViewControllers are set as childViewControllers of your new UINavigationControllers.
And remember you need to set your supported orientations with the key "Supported interface orientations" on your info.plist.
Create a SubClass of UINavigationController
#interface BaseNavigationController : UINavigationController
#end
#implementation BaseNavigationController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
BOOL shouldAutorotateBool = NO;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
// iOS6/7 support
- (NSUInteger) supportedInterfaceOrientations {
NSUInteger interfaceOrientation = UIInterfaceOrientationMaskPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
-(BOOL)shouldAutorotate
{
BOOL shouldAutorotateBool = NO;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
-(BOOL) isRotate
{
if ([[self.viewControllers lastObject] isMemberOfClass:NSClassFromString(#"VideoVC")]) {
return YES;
}
return NO;
}
#end
And in that particular viewController:
#import "VideoVC.h"
#interface VideoVC ()
#end
#implementation VideoVC
#pragma mark- Methods for device orientation handling
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
- (BOOL)shouldAutorotate
{
return YES;
}
#end
In my app I am using MPMoviePlayerController. I need to display movie player in both landscape and portrait orientations. I only want movie player to display like this and other screens should only be portrait oriented. I am stuck and getting no solutions. From settings I've checked three modes as shown below.
I am using ios 7 and xcode 5. Thanks
In your ViewController which contains MPMoviePlayerController, implement this (iOS6 and above):
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll; //allow rotate landscape, portrait
}
In other viewControllers:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown; // portrait only
}
To iOS version is lower than 6, implement this method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- (BOOL)shouldAutorotate
Note that: ViewController which contain above VCs should implement above methods
Create Inherited class of NavigationController
BaseNavigationController.h
import
#interface BaseNavigationController : UINavigationController
#end
BaseNavigationController.m
pragma mark- Orientation changes handling
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
BOOL shouldAutorotateBool = NO;
if ([self isRotate])
{
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
// iOS6/7 support
- (NSUInteger) supportedInterfaceOrientations {
NSUInteger interfaceOrientation = UIInterfaceOrientationMaskPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
-(UIInterfaceOrientation) preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationPortrait;
if ([self isRotate]) {
if([[self.viewControllers lastObject] respondsToSelector:#selector(preferredInterfaceOrientationForPresentation)]) {
interfaceOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
}
return interfaceOrientation;
}
-(BOOL)shouldAutorotate
{
BOOL shouldAutorotateBool = NO;
if ([self isRotate])
{
if([[self.viewControllers lastObject] respondsToSelector:#selector(shouldAutorotate)])
shouldAutorotateBool = [[self.viewControllers lastObject] shouldAutorotate];
}
return shouldAutorotateBool;
}
-(BOOL) isRotate
{
if ([[self.viewControllers lastObject] isMemberOfClass:NSClassFromString(#"VideoVC")]) {
return YES;
}
return NO;
}
**And the particular viewController use the following Code for orientation**
pragma mark- Methods for device orientation handling
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeLeft;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Best way to change orientation only for the MoviePlayer
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[self.window.rootViewController presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
First you should use methods for the iOS6 presented in UIViewController documentation if you are making your app for iOS6. Orientation method like shouldAutorotateToInterfaceOrientation is deprecated in iOS6, alternate method for iOS6 is shouldAutoRotate. You should only use the old method if your app is supporting also iOS5.
Second If you are using UINavigationcontroller in your application and you need to have different interface orientations then navigationController could mess up the interface orientation in the application. Possible solution (worked for me) is to implement a custom UINavigationController and override the interface orientation methods within that custom UINavigationController class, this will make your viewControllers rotate according to the orientation you set because your controllers are pushed from the UINavigationController. Don't forget to add those methods in your particular viewController also.
CustomNavigationController.h
#interface CustomNavigationController : UINavigationController
#end
CustomNavigationController.m
#implementation CustomNavigationController
//overriding shouldRotate method for working in navController
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
I have a table view and when the cell is tapped in table, I'm pushing another view controller
as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
PriceChart *vc = [storyboard instantiateViewControllerWithIdentifier:#"pricechart"];
[self.navigationController pushViewController:vc animated:YES];
}
Now My question is: the view controller I'm going to show should be in land scape mode but it is in portrait mode.
Another question is how to open different view controllers when different cell is tapped. I tried it using indexpath.row but is there any other way using storyboard?
shouldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation
The above methods don't get called of a UIViewController if they are inside any UINavigationController. If these methods are declared inside UINavigationController then they will get called.
For solving this make a class lets call it OrientationEnabledNavigation, it is a subclass of UINavigationController. Then implemented shouldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation methods inside OrientationEnabledNavigation.
OrientationEnabledNavigation.h
#import <UIKit/UIKit.h>
#interface OrientationEnabledNavigation : UINavigationController
#end
OrientationEnabledNavigation.m
#import "OrientationEnabledNavigation.h"
#interface OrientationEnabledNavigation ()
#end
#implementation OrientationEnabledNavigation
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
// return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Then if you want to use navigation controller in your project then use OrientationEnabledNavigation. After that if you implement shouldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation these method inside your viewcontroller then they will get called.
The in you viewcontroller implement these:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Another way is that add some code beginning of your app delegate:
For UITabBarController
#implementation UITabBarController (AutoRotationForwarding)
-(BOOL)shouldAutorotate
{
if ([self.selectedViewController respondsToSelector:#selector(shouldAutorotate)]) {
return [self.selectedViewController shouldAutorotate];
}
else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if ([self.selectedViewController respondsToSelector:#selector(supportedInterfaceOrientations)]) {
return [self.selectedViewController supportedInterfaceOrientations];
}
else {
return UIInterfaceOrientationMaskAll;
}
}
#end
For UINavigationController
#implementation UINavigationController (AutoRotationForwarding)
-(BOOL)shouldAutorotate
{
if ([self.topViewController respondsToSelector:#selector(shouldAutorotate)]) {
return [self.topViewController shouldAutorotate];
}
else {
return YES;
}
}
-(NSUInteger) supportedInterfaceOrientations {
if([self.topViewController respondsToSelector:#selector(supportedInterfaceOrientations)])
{
return [self.topViewController supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
#end
Hope this helps.. :)
This is how you can force to landscape
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
In class which is in landscape mode:
- (NSUInteger)supportedInterfaceOrientations
{
// return orientation that you want
//return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
//return UIInterfaceOrientationIsPortrait(toInterfaceOrientation);
}
If you use UINavigationController, you should inherit your navigationController from UINavigationController and implement
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return [[self.viewControllers lastObject] shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}
Try This..
This demo has solved my problem...
https://github.com/alloy/ForceOrientationTest
You can force an orientation refresh as explained here and the other answers in that question.
As for the second question, just populate a UITableViewController with either static cells or dynamic prototype cells. Then control+drag from the cell to another view controller in your Storyboard. You'll have the same Push/Modal/Custom actions that show up for buttons.
I have a diagram very complicated, and I want to fix portrait UIViewController inside multiple TabBarController and NavigationController, I'm using this code in UIViewController do fix TabBar and Navigation:
#implementation UINavigationController (LoginIphone)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
#implementation UITabBarController (ChannelViewController)
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// You do not need this method if you are not supporting earlier iOS Versions
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
and this code inside do fix UIViewController but it doesn't work.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait);
}
Anyone have solution for this problem, thank to read this article!
Your supportedInterfaceOrientations method should be:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
project Targets --> click on "Summary" tab and choose your Orientation in "Supported interfaces Orientations"
I saw this stackoverflow post:shouldAutorotateToInterfaceOrientation is not working in iOS 6. The answer was to add a category called RotationIn_IOS6. I have done that and the views for the different viewcontrollers are working correctly in iOS6. The problem is in iOS5.
I only need a few views to rotate in all directions, the rest should be in portrait or either PortraitUpsideDown. The problem i face is that either all don't rotate(code1) or after it rotates to landscape, it remains in the same orientation until you rotate back to portrait(code2).
Code1:
#implementation UINavigationController (RotationIn_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
#end
Code 2:
#implementation UINavigationController (RotationIn_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if([self.visibleViewController isKindOfClass:[MyClassToRotate class]])
{
return [self.visibleViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
else
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
Need some guidance on this. Not sure how to solve this.
EDIT:
Code3:
1) Removed the shouldAutorotateToInterfaceOrientation from the Category.
2) Added this code to my particular class
- (BOOL)shouldAutorotate
{
//returns true if want to allow orientation change
return TRUE;
}
- (NSUInteger)supportedInterfaceOrientations
{
//decide number of origination tob supported by Viewcontroller.
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
//from here you Should try to Preferred orientation for ViewController
return TRUE;
}
Result -> All the viewcontroller locked in portrait. Cannot access PortraitUpsideDown. Once in my viewcontroller, it can rotate, but when you get out of the viewcontroller, locked in landscape..
EDIT 2:
Each viewcontroller contains these code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate {
return NO;
}
No need to override shouldAutorotateToInterfaceOrientation: in the navigation controller category instead for iOS 5 each of your view controller should implement shouldAutorotateToInterfaceOrientation: with the supported orientation. The supported orientations determined by the container controller(navigation controller) is only in the iOS6 and above. In lower version it will call the shouldAutorotateToInterfaceOrientation: of the child view controller which is going to display
To solve that problem i've subclassed UINavigationController instead of use a category:
MyNavigationcontroller.h
#import <UIKit/UIKit.h>
#interface MyNavigationcontroller : UINavigationController
#end
MyNavigationcontroller.m
#import "MyNavigationcontroller.h"
#interface MyNavigationcontroller ()
#end
//Set your init...
-(BOOL)shouldAutorotate {
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(#"YourClass")])
return YES;
}
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(#"YourClass")]) {
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortraitUpsideDown;
}
#end
Then in each viewcontroller override:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationMaskPortraitUpsideDown);//or your orientation
}
Then, at launch, in the didFinishLaunchingWithOptions: of your app delegate:
NSString *reqSysVer = #"6.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
self.navigationController = [[MyNavigationcontroller alloc] initWithRootViewController:masterViewController];//IOS 6
}else{
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
}
self.window.rootViewController = self.navigationController;
The simplest way is Target->General->Deployment Info and tick the orientations you want. E.g. tick only portrait and the app will not auto rotate.