iPhone is still autorotating


#1

I added the the following code from p. 263 to both ItemsViewController.m and DetailViewController.m

The interface is still autorotating on the iPhone. I have checked the code several times and if I’ve made a typo, I’m just not seeing it.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io { if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { return YES; } else { return (io == UIInterfaceOrientationPortrait); } }

I appreciate any help.


#2

Do you mean you don’t want the autorotation? If so, then you should return NO:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        return YES;
    } else {
        return NO;
    }
}

As an aside, rather than directly testing you might consider using the Interface Orientation Macros: UIInterfaceOrientationIsPortrait () or UIInterfaceOrientationIsLandscape ():

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        return YES;
    } else {
        return UIInterfaceOrientationIsPortrait (io);
    }
}

#3

Thanks for the response!

It makes sense to ‘return NO;’, however, that’s not the example in the book and I’m wondering why I couldn’t get it working as presented in the book.

When first troubleshooting this problem, I did try to return ‘NO’ at the end of ‘- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io’.
However, it was still autorotating on the iPhone only in ‘ItemsViewController’, not in ‘DetailViewController’. In ‘DetailViewController’, the code was working properly.
So, I changed to code back to ‘return (io == UIInterfaceOrientationPortrait);’. Still the same behavior. On another attempt to try ‘return NO;’, it worked. So, out of curiosity, I tried ‘return (io == UIInterfaceOrientationPortrait);’ again and it worked. I had actually tried going back and forth several times between both examples before actually getting it to work both ways. I used both ‘copy and paste’ and retyping the code. Now that it is working, It seems as though this might have been some erratic behavior on the part of the device.


#4

With IOS 6 out now, I’m trying to move away from the deprecated shouldAutorotateToInterfaceOrientation: message. Instead, the documentation says rotation should managed by overriding shouldAutorotate and supportedInterfaceOrientations for each view controller. Documentation also says that supportedInterfaceOrientations is only called if shouldAutorotate returns YES. I overrode these two methods for itemsViewController and detailedViewController. Unfortunately, shouldAutorotate never gets called. However, supportedInterfaceOrientations does get called, but the mask appears to be ignored.

Do I need to implement shouldAutorotate and supportedInterfaceOrientations for the navController, which is the topmost presented view controller. How would this be done? We instantiated a UINavigationController programmatically in the appDelegate. Not sure how to override methods without creating a class file for the controller.

Info.plist includes all 4 orientations. No matter what I do, the iPad rotates for all orientations and the iPhone rotates for all but upside down. This is the default behavior that I’m not successfully overriding.


#5

Didn’t get any response to my questions about IOS6 automation, so I looked into it myself. I’m sharing in case it benefits others. I’m sure when Joe updates the book, he’ll give a much better explanation. There are two sources of autorotation configuration; The application object and the root view controller (except in the case where there is a modally presented view controller, then it is the topmost presented controller). The masks are AND’ed to determine at runtime what orientations are supported.

The application rotation capability is set in the Info.plist or application:supportedInterfaceOrientationsForWindow sent to the app delegate.
The root view controller for Homepwner is the navController.

I changed Homepwner-Info.plist to include all orientations (by default, it had already had all but upside down set). Then I subclassed UINavigationController and called it HomepwnerNavigationController.

In HomepwnerNavigationController.m, I overrode the following:

[code]- (BOOL)shouldAutorotate
{
return YES;
}

  • (NSUInteger)supportedInterfaceOrientations
    {
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
    return UIInterfaceOrientationMaskPortrait;
    } else {
    return UIInterfaceOrientationMaskAll;
    }
    }[/code]

and then in HomepwnerAppDelegate.m, I instantiated the subclassed controller

HomepwnerNavigationController *navController = [[HomepwnerNavigationController alloc] initWithRootViewController:itemsViewController];

This gives the same rotation behavior of the deprecated solution in the book (portrait only for phones and all orientations for pads)


#6

Good work on creating a UINavController for the masks! That’s kind of advanced maneuvers the easiest way I found and the reason I think they deprecated the method is that you can now set up this in your deployment info. It’s the easy way out but if you want to have some screens locked in orientation and others not masks will be required. If not you can set this up here for ease.


#7

Correct, this changed with iOS 6. The beauty is that you probably don’t ever have to override supportedInterfaceOrientation because it does what you want by default: all but upside down for iPhone, all for iPad.


#8

Thanks phancock. Your method worked for me: “subclassed UINavigationController and called it HomepwnerNavigationController.”


#9

Thank you phancock! This was giving me a major headache. As much as I enjoy programming, it can be very frustrating at times.


#10

Thank you Phonecock, It is great solution to build another subclass of NavigationController.


#11

So if trying to do this programmatically in iOS6 will: (BOOL)shouldAutorotate & (NSUInteger)supportedInterfaceOrientations only work if you subclass UINavigationController (assuming that’s your rootcontroller)? I spent a couple of hours to make it work, and couldn’t find another way to make that work.

On the flip side if you’re looking for a different method you could either just hardcode the values in project, targets, summary and choose the orientations you want.

Or in the AppDelegate you could always add:

  • (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

and add the views in there as well.