I upgraded to xCode 4.2 and it's new Storyboards feature. However, could not find a way to support both portrait and landscape.
Of course, I did it programmatically, with 2 views, one for portrait and one for landscape, like in old days, and:
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
self.view = self.landscapeView;
}
else
{
self.view = self.portraitView;
}
But I was looking for a way to do this automatically somehow. I mean, it's xCode 4.2 now, I expected more from it. Thanks all.
==================================
TEMPORARY SOLUTION:
I will present here a temporary solution. I say it's temporary, because I am still waiting for Apple guys to do something really intelligent about this.
I created another .storyboard file, called "MainStoryboard_iPhone_Landscape", and implemented the landscape view controllers there. Actually, it's exactly like normal(portrait) .storyboard, but all screens are in landscape mode.
So I will extract the ViewController from landscape storyboard, and when rotation occurs, just change self.view with the new viewController's view.
1.Generate Notifications when orientation changes:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
2.Look for notifications:
[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
// We must add a delay here, otherwise we'll swap in the new view
// too quickly and we'll get an animation glitch
[self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}];
3.Implement updateLandscapeView
- (void)updateLandscapeView {
//> isShowingLandscapeView is declared in AppDelegate, so you won't need to declare it in each ViewController
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !appDelegate().isShowingLandscapeView)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone_Landscape" bundle:[NSBundle mainBundle]];
MDBLogin *loginVC_landscape = [storyboard instantiateViewControllerWithIdentifier:@"MDBLogin"];
appDelegate().isShowingLandscapeView = YES;
[UIView transitionWithView:loginVC_landscape.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{
//> Setup self.view to be the landscape view
self.view = loginVC_landscape.view;
} completion:NULL];
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) && appDelegate().isShowingLandscapeView)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
MDBLogin *loginVC = [storyboard instantiateViewControllerWithIdentifier:@"MDBLogin"];
appDelegate().isShowingLandscapeView = NO;
[UIView transitionWithView:loginVC.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{
//> Setup self.view to be now the previous portrait view
self.view = loginVC.view;
} completion:NULL];
}}
Good luck to everybody.
P.S: I will accept Ad Taylor's answer, because, after much time waiting and searching for a solution, I finished up implementing something inspired from his answer. Thanks Taylor.
This is an old question but I read this earlier in the day and then had to spend a fair amount of time work out a better solution. I came up with this solution from hacking up the Apple Alternate View example. Basically it is serving up a modal view for the landscape view.
#pragma mark Rotation view control
- (void)orientationChanged:(NSNotification *)notification
{
// We must add a delay here, otherwise we'll swap in the new view
// too quickly and we'll get an animation glitch
[self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !self.isShowingLandscapeView)
{
[self performSegueWithIdentifier: @"toLandscape" sender: self];
self.isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && self.isShowingLandscapeView)
{
[self dismissModalViewControllerAnimated:YES];
self.isShowingLandscapeView = NO;
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}