14
votes

I have my iPad application created using the SplitView template. I wonder what is the best way to restrict my application to landscape mode?

I have tried overriding shouldAutorotateToInterfaceOrientation: method in DetailViewController.m

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

but 4.2 GM is still buggy and it fails to show the controller view. What other choices do I have?

Thanks in advance.

UPDATE1

  • I have already filed a bug report: Bug ID #8620135

  • My app is almost finished and I have to find a work-arround since I don't think they are going to solve this before 4.2 officially comes out (GM is already out!)

    In order to recreate the bug, just use SplitView template and override above method in any of the UIViewControllers (RootViewController or DetailViewControllers)

UPDATE2

I have found a work-around. (See UPDATE3 for the complete work-around)

Set UISupportedInterfaceOrientations only to support Landscape , this will force the app to start in landscape mode allowing DetailViewController to start correctly(hence shown correctly)

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

But if you rotate the device, it turns Portrait mode!!!, so is still necessary to override shouldAutorotateToIntercafeOrientation: as above

Discussion:

If this wouldn't be a bug I would expect a warning or execution error, exception or something when starting the app in a orientation that is not supported by the view controller. Besides, why only DetailViewController does not show? If this would be specification, then RootViewController should also fail to load then. Don't you think? thanks for you help... ;)

UPDATE3

After further tests I have realized that above work-around does not work in some cases. For example when starting the app when the device is in landscape won't work!. The real problem seems to be that in iOS4.2GM UISplitViewController needs all its controllers have all rotations to be available at its load time. So is necessary to trick him so it loads in Landscape mode and then not allow him to rotate its view controllers.

So here is the new work-around for this annoying iBug.

Step1: Set Info.plist like so:

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

Step2 Set a new flag in DetailViewController.m or .h (from SplitView Template)

BOOL lockRotation = NO; //WORK-ARROUND: Bug ID# 8620135.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    //WORK-ARROUND: Bug ID# 8620135.
    if (lockRotation) {
        return UIInterfaceOrientationIsLandscape(interfaceOrientation);
    }else{
        return YES;
    }
}
- (void)viewDidLoad {
    [super viewDidLoad];
    //set NO here since this is called before shouldAutorotateToInterfaceOrientation method is called
    lockRotation = NO; //WORK-ARROUND: Bug ID# 8620135.
}
- (void)viewDidAppear:(BOOL)animated {
    //set YES as soon as possible, but after shouldAutorotateToInterfaceOrientation method was called
    lockRotation = YES; //WORK-ARROUND: Bug ID# 8620135.
    [super viewDidAppear:animated];
}

IMPORTANT NOTE: Please note that this bug only appears when the UISplitViewController is loaded and not everytime the its view appears. Hence, to see this bug make sure the app was terminated before.

4
the question states you are making the change in DetailViewController, is that the correct controller to be overriding the method?Aaron Saunders
@Aaron it does not matter In what controller I make the change. (In RootViewController or DetailViewController) The result is the same.nacho4d
basically UISupportedInterfaceOrientations, does absolutely nothing. To set the orientation when the app starts set UIInterfaceOrientation in the plist. (it's friendly name is Initial Interface Orientation)Jonathan.

4 Answers

2
votes

I asked a question with a bounty of 500 that seems to be the same thing you're facing.

From my limited experience it is much easier to make a landscape-only iPhone app than a landscape-only iPad app. I'm not sure why there is any difference, but the steps Apple says to take to make it landscape-only do not work on their own.

1
votes

Try this (it works):

-(BOOL)shouldAutorotateToInterfaceOrientation(UIInterfaceOrientation)toInterfaceOrientation {
    if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
        return YES;
    }
    else 
    {
        return NO;
    }
}
0
votes

Check out this iPhone app in landscape mode, if you haven't already. I was going to suggest simply adding UISupportedInterfaceOrientations to your Info.plist and specifying the two landscape orientations. But, apparently, this is not sufficient, according to answers to cited question.

0
votes

I believe this is a BUG, I faced this problem also. It is something to do with

UIInterfaceOrientationLandscapeLeft

To replicate this situation:

1) Create a new iPad project using UISplitViewController template

2) Edit info.plist

Supported interface orientations
-Landscape (left home button)
-Landscape (right home button)

3) DetailViewController.m

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//    return YES;
 NSLog(@"RotateToInterface:[%d] vs LandscapeLeft[%d]", interfaceOrientation, UIInterfaceOrientationLandscapeLeft);
 return interfaceOrientation == UIInterfaceOrientationLandscapeLeft;
}

4) Run it....You will see a blank black view. and no matter how you turn. "UIInterfaceOrientationLandscapeLeft" never detected.

By the way, nacho4d's adding BOOL check work-around is working. Thumbs UP :)