shouldAutorotateToInterfaceOrientation is not being called - objective-c

Hi i am now problem with orientation of viewcontroller. the following is my .h file.
#interface IPad_HomeViewController : UIViewController <UINavigationControllerDelegate>{
UIAlertView *alertWithYesNoButtons;
}
#property (weak, nonatomic) IBOutlet UILabel *lblStatus;
#end
i implement the following method in .m file.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return NO;
}
then i made a breakpoint. i realized shouldAutorotateToInterfaceOrientation is totally not being called. don't know why it is not being called.
pls advise me.
thanks

I think it is because your UINavigationController handles the call. Implement the following to send it back to the viewController.
- (BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

Rotation support changed a lot between iOS 5 and iOS 6.
Go to your project's target summary page and check "iPhone/Ipod Deployment Info" and there "Supported Interface Orientations". Have you enabled device rotation?

Related

iOS 6 supportedInterfaceOrientations issue

In my view controller, I implement two methods for controlling interface orientation:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate
{
return YES;
}
In the supportedInterfaceOrientations method, I return UIInterfaceOrientationMaskPortrait but at that time I realized that the shouldAutorotate method is not being called.
But I change to return UIInterfaceOrientationPortrait in the supportedInterfaceOrientations method. The shouldAutorotate method is being called, but there is an error that mentions in following:
UIApplicationInvalidInterfaceOrientation, reason: 'Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
By the way, I select all orientations in the supported interface orientations.
EDITED
i use viewController and embed with navigationController.
here is AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate,UINavigationControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (readonly, strong, nonatomic) UINavigationController *navController;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
#end
in didFinishLaunchingWithOptions method under AppDelegate.m
navController = (UINavigationController *)self.window.rootViewController;
IPad_HomeViewController *rootVC=(IPad_HomeViewController *)navController.topViewController;
rootVC.managedObjectContext = self.managedObjectContext;
return YES;
in my IPad_HomeViewController,
#interface IPad_HomeViewController : UIViewController <UINavigationControllerDelegate>
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#end
- (BOOL) shouldAutorotate {
return YES;
}
// for landscape
- (NSInteger) supportedInterfaceOrientations {
return (1 << UIInterfaceOrientationLandscapeLeft) |
(1 << UIInterfaceOrientationLandscapeRight);
}
As noted above, check out the mask values for specific orientations : UIInterfaceOrientationMask values.UIInterfaceOrientationMask
Two points:
Your error message makes complete sense because it makes no sense to use UIInterfaceOrientationPortrait as a return value from supportedInterfaceOrientations, which is returning a bit mask. Use one of the UIInterfaceOrientationMask values.
You seem to be concerned that if you use the proper UIInterfaceOrientationMaskPortrait, that iOS doesn't appear to call shouldAutorotate. It may only call shouldAutorotate if, having considered the physical device's physical orientation and the app's current orientation against the supportedInterfaceOrientations that a rotation might be needed. Why should it check shouldAutorotate if it concludes that the device is in an acceptable orientation already?
See supportedInterfaceOrientations and Handling View Rotations for more information.
I know this sounds pretty elementary, but I was wracking my brain to figure out orientation issues while testing on my iPhone - I had the physical auto lock mode in Portrait mode - so nothing I changed programmatically mattered - thought this should be troubleshooting step number 1!
In order to change the orientation setting, select menu Targets->Summary-> Supported Device Orientations and change as following.
If the buttons for the orientation are dark then that means you have selected it as one of the orientation.
rather than using an integer to declare the orientation why don't you use a bool and plug in a if statement in there to detect whatever orientation you want. here is a example code that i hope would help you:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
return YES;
}
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
return YES;
}
return NO;
}
you can add all of the orientations in the if statement and it should work just fine. adrian
Edit:
and if you want to have an option for ios 6 the below code should work just fine for you.
- (BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
you can change just about all the supported orientations with this in ios 6. happy coding
EDIT 1:
to rotate only certain viewcontrollers in a certain way, just use the ios 6 code that i posted above in all viewcontrollers. here are the steps:
in the project level where all four internfaceorientations are located, go ahean and turn everything off so app would go to default.
implement the ios 6 code that i supplied in all viewcontrollers.
rather than yes declare no in shouldautorotate method.
in the second method, plug in any type of orientation you want.
this should do the trick for you. happy coding

How do I make rotation work properly in iOS 6 GM in a tab bar app?

Rotation was working JUST FINE with iOS 5 and now it doesn't work at all. I had it set so that ALL of my views stayed Portrait exception when on Tab 1 when a certain view was open, then users could rotate and it would show a coverflow-style view.
My setup is that I create my tabbar at runtime in the AppDelegate. I then set it as the main root view:
self.window.rootViewController = self.tabBarController;
But ALL of my views, on all tabs, now rotate left or right no matter what. And I've tried adding the new code (from multiple examples in the forums) to no avail.... I breakpoint everything and NO rotation code ever gets called when I rotate my phone.
Each TabController has within it a NavigationController and then within that has my main views with all of my UI.
Any ideas or pointers on how to do rotation correctly in iOS 6? Very frustrating because this is the final problem I need to fix before I can ship.
This will get you up and running. Ultimately you really should subclass these UIKit classes instead of using categories, but unfortunately that will not work for third party libraries which are not yet fixed for iOS 6. These categories should work for everything without requiring you to muck about in other people's code.
I have yet to see any solution for the UITabBarController or UINavigationController issues that do not involve subclassing (or writing a category). I wish one existed, though.
Make sure you import the three .h files (or one if you choose to add them all to a single file) at the top of your Prefix.pch file. You must make sure this code is loaded ASAP!
UITabBarController+LegacyRotation.h
#import <UIKit/UIKit.h>
#interface UITabBarController (LegacyRotation)
#end
UITabBarController+LegacyRotation.m
#import "UITabBarController+LegacyRotation.h"
#implementation UITabBarController (LegacyRotation)
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
#end
UINavigationController+LegacyRotation.h
#import <UIKit/UIKit.h>
#interface UINavigationController (LegacyRotation)
#end
UINavigationController+LegacyRotation.m
#import "UINavigationController+LegacyRotation.h"
#implementation UINavigationController (LegacyRotation)
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
#end
UIViewController+LegacyRotation.h
#import <UIKit/UIKit.h>
#interface UIViewController (LegacyRotation)
#end
UIViewController+LegacyRotation.m
#import "UIViewController+LegacyRotation.h"
#implementation UIViewController (LegacyRotation)
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger ret = 0;
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortrait]) {
ret |= UIInterfaceOrientationMaskPortrait;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationPortraitUpsideDown]) {
ret |= UIInterfaceOrientationMaskPortraitUpsideDown;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeLeft]) {
ret |= UIInterfaceOrientationMaskLandscapeLeft;
}
if ([self shouldAutorotateToInterfaceOrientation:UIInterfaceOrientationLandscapeRight]) {
ret |= UIInterfaceOrientationMaskLandscapeRight;
}
return ret;
}
- (BOOL)shouldAutorotate
{
return YES;
}
#end
I just needed to add the following method in the appDelegate , in order for the rotation to
work on ios 6.
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:
(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
Where as for ios 4 & 5 we still have to use :
(BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation in the specific view controller

Where can I set a UINavigationControllers supportedOrientations?

I am using iOS 6.0 beta and my rotations do not work anymore.
Where can I set a UINavigationControllers supportedOrientations?
According to this http://news.yahoo.com/apple-ios-6-beta-3-changes-182849903.html
a UINavigation Controller does not consult their children to determine whether they should autorotate.
I am not using shouldAutorotateToInterfaceOrientation: anymore as it is deprecated.
Instead I am using supportedInterfaceOrientations: and shouldAutoRotate: and they are working fine until I place a ViewController into a NavigationController (as a Child).
From then on the orientations specified in the ViewController do not work anymore.
It seems it is using the orientations set by the navigation controller (UIInterfaceOrientationMaskAllButUpsideDown)
How can I set the InterfaceOrientations for the NavigationController so that my ViewControllers are locked to Portrait-Orientation?
Do I have to subclass UINavigationController and set the InterfaceOrientations there? Isn't it bad practise to subclass UINavigationController still in iOS 6.0?
Thanks for you help heaps!
Cheers!
If you want it to consult it's children again you can add a category to UINavigationController
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
#end
Subclass UINavigationController
//OnlyPortraitNavigationController.h
#interface OnlyPortraitNavigationController : UINavigationController
//OnlyPortraitNavigationController.m
#implementation OnlyPortraitNavigationController
- (BOOL)shouldAutorotate {
return NO;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait; //for locked only Portrait
}
present new subclass navigationController with your portrait ViewController
SomeViewController *onlyPortraitVC = [[SomeViewController alloc]init];
OnlyPortraitNavigationController *portraitNav = [[OnlyPortraitNavigationController alloc]initWithRootViewController:onlyPortraitViewController];
[self presentViewController:portraitNav animated:YES completion:NULL];
this is work on my app hope it can help you.

UITabBarController Rotation Issues in ios 6

Ack! I had my tabbar rotation issues resolved finally in iOS 5, but iOS 6 and xcode seem to have broken things... here is what I have:
Target App Summary includes: Supported Interface Orientations - Portraint, Landscape Left, Landscape Right
Every Single View in the App has the following methods:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return ((interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown) &&
(interfaceOrientation != UIInterfaceOrientationLandscapeLeft) &&
(interfaceOrientation != UIInterfaceOrientationLandscapeRight));
} else {
return YES;
}
}
- (BOOL)shouldAutorotate
{
NSLog(#"am I called1?");
return NO;
}
-(NSUInteger)supportedInterfaceOrientations{
NSLog(#"am I called?");
return UIInterfaceOrientationMaskPortrait;
}
In the views that are not part of the tab bar, rotation is blocked. In ALL the views of the tabbar (there are 5) the app never calls ShouldAutorotate and so rotates. It does seem supportedInterfaceOrientations gets called once when a view loads, but not when it appears if I switch between views, because I get the NSLog, but it seems to ignore the MaskPortrait setting.
I have to leave the landscape enabled in the target because I have a single video player view that needs to rotate (and it does so, fine)
Is this a tabbar bug in iOS 6? Do I need to disable the rotation of the views differently? The shouldautorotatetointerfaceorientation worked great in ios 5
I've been at it for a while
Thanks,
Zack
Zack, I ran into this same issue. It's because you have your viewController embedded inside of a TabBar Controller or UINavigationController and the calls to these methods are happening inside those instead of your normal View (Changed in iOS6).
I ran into this issue because I was presenting a viewController embedded inside a UINavigationController on all my modal views that had Navigation to different views (Signup Process, Login, etc).
My simple fix was to create a CATEGORY for UINavigationController that includes these two methods. I have shouldAutorotate returning NO anyway because I don't want my modal views rotating. Your fix may be this simple, give it a try. Hope it helps.
I created a category and named it autoRotate and selected theUINavigationController option. The M+H file are below.
#import "UINavigationController+autoRotate.h"
#implementation UINavigationController (autoRotate)
-(BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
#end
... and the category .h:
#import <UIKit/UIKit.h>
#interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
#end
If you have a tab bar like I did, the only thing you need to do is to add the following to your delegate .m file,
#import "AppDelegate.h"
//UITabBarController category to set the view rotations for ios 6
#implementation UITabBarController (Background)
-(BOOL)shouldAutorotate
{
//I don't want to support auto rotate, but you can return any value you want here
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
//I want to only support portrait mode
return UIInterfaceOrientationMaskPortrait;
}
#end
/////here starts the implementation of the app delegate which is gonna be whatever you currently have on your .m delegate
#implementation AppDelegate
// delegate methods and other stuff
#end
I also had the issue that I needed some views to rotate and others not with several Navigation Controllers. I did this by telling the NavigationController to look in the view controller. Here is what I did.
I create a UINavigationController class called RootNavigationController and designated that class as the Custom Class for the Navigation Controllers in storyboard. In the RootNavigationController.m I added the following methods;
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
In each view controller .m file I also added the following methods.
- (BOOL)shouldAutorotate {
//return yes or no
}
- (NSUInteger)supportedInterfaceOrientations{
//return supported orientation masks
}
Doing this allows me to set orientation for each view in its view controller.
Worked for me anyway…
My situation is:
UITabBarController has 2 items: 2 Navigation controller
UINavigationController1 withRootView: ViewController1
UINavigationController2 withRootView: ViewController2.
Now i want ViewController1 set shouldAutorotate:NO/maskPortrait and
ViewController2 set shouldAutorotate/MaskAll.
So my implement: Create UITabBarController category and UINavigationCntroller category like
UITabBarController+autoRotate.h
#interface UITabBarController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
#end
UITabBarController+autoRotate.m
#import "UITabBarController+autoRotate.h"
#implementation UITabBarController (autoRotate)
- (BOOL)shouldAutorotate {
return [self.selectedViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.selectedViewController supportedInterfaceOrientations];
}
#end
UINavigationController+autoRotate.h
#interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
#end
UINavigationController+autoRotate.m
#implementation UINavigationController (autoRotate)
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
#end
UIViewController1.m
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;;
}
UIViewController2.m
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
It worked like a charm!
In my case, I had a navigation controller embedded within a UITabBarController, and what worked was creating a category like Kunani defined, but extendind UITabBarController instead of UINavigationController. It worked like a charm :)
#import "UINavigationController+autoRotate.h"
#implementation UINavigationController (autoRotate)
-(BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
#end
And .h file:
#import <UIKit/UIKit.h>
#interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
#end
This will do it in Swift
extension UITabBarController {
public override func shouldAutorotate() -> Bool {
if let selected = self.selectedViewController {
return selected.shouldAutorotate()
} else {
return false
}
}
public override func supportedInterfaceOrientations() -> Int {
if let selected = self.selectedViewController {
return selected.supportedInterfaceOrientations()
} else {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
}
}
extension UINavigationController {
public override func shouldAutorotate() -> Bool {
return self.visibleViewController.shouldAutorotate()
}
public override func supportedInterfaceOrientations() -> Int {
return self.visibleViewController.supportedInterfaceOrientations()
}
}
https://stackoverflow.com/a/30632505/2298002
there are a lot of ambiguous or unforeseen results when handling this situation, especially when it comes to maintaining the orientation for only a specific view controller and not effecting the rest of the app. this algorithm seems to hand all for me
https://stackoverflow.com/a/30632505/2298002
You should add this thing in the UIViewController1.m to make sure that the previous orientation status is reconstructed:
(void)viewDidAppear:(BOOL)animated
{
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:")
withObject:(id)UIInterfaceOrientationPortrait];
}
Perfect!

Help with Xcode - Incorrect implementation of class 'secondview' + method definition for '-switchview:' not found

I am trying to create an application in Xcode that will switch to a new view when the phone is rotated from one orientation to another.
Here is the "switchviewcontroller.h" file code:
#import <UIKit/UIKit.h>
#interface SwitchViewController : UIViewController {
}
-(IBAction)switchview:(id)sender;
#end
-----------------------------------------------------------------
And here is the "switchviewcontroller.m" file code:
----------------------------------------
#import "SwitchViewController.h"
#import "secondview.h"
#implementation SwitchViewController
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if((fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
{
[[secondview alloc] initWithNibName:#"secondview" bundle:[NSBundle mainBundle]];
}
}
I get the 2 warnings showed in the question, and it also doesn't work.
well the method definition not found is saying exact that ..... in the code you posted there is no switchview method. The incorrect implementation error message implies that the secondview class doesn't conform to a uiview.
You declared
-(IBAction)switchview:(id)sender;
but you did not implement it.
In your .m file, add
-(IBAction)switchview:(id)sender
{
//here is the implementation of the switch view method
}
Also, it looks like you're creating an instance of secondview whenever the view is rotated so you will leak one secondview instance each time the interface changes orientation.