UIViewController gets stuck in horizontal orientation after portrait rotation - iphone

View Controller A displays View Controller B in horizontal orientation
#pragma mark Rotation Delegate Methods
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
[landscapeChartViewController.chartImageView reloadWithUrl:
[NSString stringWithFormat:#"someurl",[symbol uppercaseString]]];
NSLog(#"showing chart");
[self presentModalViewController:landscapeChartViewController animated:NO];
}
}
This works fine. View Controller B shows up in landscape orientation. Here is View Controller B's implementation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"dismissing chart");
[self.parentViewController dismissModalViewControllerAnimated:NO];
}
}
The problem is, when I go back into portrait orientation to show View Controller A, View Controller A is stuck in landscape orientation. How can I fix this?

EDIT: after reading your comment, I suggest trying to use willRotateToInterfaceOrientation:duration: instead of willAnimateRotationToInterfaceOrientation, like this:
controller A:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
[landscapeChartViewController.chartImageView reloadWithUrl:
[NSString stringWithFormat:#"someurl",[symbol uppercaseString]]];
NSLog(#"showing chart");
[self presentModalViewController:landscapeChartViewController animated:NO];
}
}
controller B:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"dismissing chart");
[self.parentViewController dismissModalViewControllerAnimated:NO];
}
}
I do more or less the same in a project of mine, only between two non modal views.

One option is to move your code from willAnimateRotationToInterfaceOrientation: to didRotateFromInterfaceOrientation: and use self.interfaceOrientation in place of toInterfaceOrientation.

View Controller B shows up in landscape orientation. Here is View Controller B's implementation:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"dismissing chart");
[self dismissModalViewControllerAnimated:NO];
}
}

Did you implement the function willRotateToInterfaceOrientation? Also try using the Notification centre to notify the parent view controller that your modal view controller is rotated and then simply [self dismissModalViewControllerAnimated:YES]

I always write my orientation logic in didRotateFromInterfaceOrientation.
Here is a part of my code it works fine....
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[connectCoverLockUnlockSwitch setFrame:CGRectMake(250,6,51,31)];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){
[connectCoverLockUnlockSwitch setFrame:CGRectMake(400,6,51,31)];
[self.tableView reloadData];
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown || orientation == UIDeviceOrientationPortrait){
[connectCoverLockUnlockSwitch setFrame:CGRectMake(250,6,51,31)];
}
}
else if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationUnknown || orientation == UIDeviceOrientationFaceUp) {
//return;
}
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
[connectCoverLockUnlockSwitch setFrame:CGRectMake(570,6,51,31)];
[self.tableView reloadData];
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown || orientation == UIDeviceOrientationPortrait)
{
[connectCoverLockUnlockSwitch setFrame:CGRectMake(330,6,51,31)];
[self.tableView reloadData];
}
}

Related

How to get default LandscapeLeft Orientation in iOS5?

Sorry if this question is duplicate, but I can't find the same solution.
In iOS6, if I want to set default orientation for one UIViewController, I just use:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeLeft;
}
But how to do same in iOS5, I test both:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);//not default
}
and
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationMaskLandscapeLeft);// = return NO;
}
But the default orientation always Portrait.Any suggestion?
call the below method where you want to check the status of orientation.happy coding :-)
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self CheckForViewForOrientation:toInterfaceOrientation];
}
- (void) CheckForViewForOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
//Ur lable portrait view
}
else if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//Ur lable for landscape view
}
}
If you want to achieve this for whole application, change supported orientation UISupportedInterfaceOrientations in app.plist file
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation==UIInterfaceOrientationPortrait) {
// do some
}
return YES;
}
Include both the methods to support both 5 and 6
You need to provide
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
for that single View controller.

iPhone interface orientation change not returning to portrait orientation

So I have a view that I present modally when the interface orientation changes to landscape. However when the orientation returns to portrait and the modal view dismisses itself, the tableview from the initial view remains in landscape orientation (this table view must be only in portrait orientation)
Here is the code :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight) );
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) {
[self performSegueWithIdentifier:#"showCatChart" sender:self];
}
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self refreshTableView];
}
}
I tried to refresh the tableview but that doesn't make it portrait again ...
this could be from the view hierachy ...
NavigationController->tableView (only portrait)->tableview->landscapeViewModalController
With iOS 6, you need to implement the following:
- (BOOL)shouldAutoRotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
In your AppDelegate, you need to change the following:
[self.window addSubview:viewController.view];
to
[self.window setRootViewController:viewController];
Also, keep your current code if you want to support previous versions of iOS.
Use the following in appdelegate.
[self.window addsubview:viewcontroller];
This alone will solve your orientation problem.

UITabBar identifying portrait or landscape orientation

While, for the most part, orientation is working properly for my app, I'm having an issue testing on my iPad 1. If I have the device tipped at a relatively low angle, there are times while navigating through the tabs that the tab bar appears in landscape mode, but the page calls a portrait mode uiview and then tries to render it in landscape mode, screwing up my UI.
I'm trying to figure out if there is a method to lock down "if the tab bar appears in landscape mode, always call the landscape UIViews and if in portrait mode, always call the portrait UIView."
On each view controller I've set the following:
- (void)viewDidLoad
{
[super viewDidLoad];
// iPad-specific condition here
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
self.view = self.portraitViewiPad;
}
else {
self.view = self.landscapeViewiPad;
}
}
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// iPad-specific condition here
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
//show portrait XIB here
self.view = self.portraitViewiPad;
} else {
//show landscape XIB here
self.view = self.landscapeViewiPad;
}
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// iPad-specific interface here
return YES;
}
else
{
// For iPhone and iPod touch interface
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
}
I've also adjusted the app delegate using the method below thinking that could address the issue:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
//CALLS RELOAD METHODS HERE AND EACH UIVIEW IS PROPERLY BEING CALLED
}
UPDATE:
Corrected this issue by checking the orientation of the status bar and displaying the correct uiview accordingly. Here's how I updated my viewDidLoad methods:
if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeLeft){
NSLog(#"Left landscape detected");
self.view = self.landscapeViewiPad;
} else if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationLandscapeRight){
NSLog(#"Right landscape detected");
self.view = self.landscapeViewiPad;
} else if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait){
NSLog(#"Portrait orientation detected");
self.view = self.portraitViewiPad;
} else if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown){
NSLog(#"Upsidedown Portrait detected");
self.view = self.portraitViewiPad;
}
I think that you don't want to do test [[UIDevice currentDevice] orientation]. As the documentation notes that value can be different than the actual orientation of your app's UI. I think you'll want to rely on the calls to [UIViewController shouldRotateTo...] and [UIViewController willRotateTo...].

Issue on navigation controller while changing the orientation

I have two view controllers, in which I am using navigation controller to navigate from one view to another.....
In my first view controller I'm checking the orientation in this way in my - (void)viewDidLoad
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
//Do this task
}
else
{
//Do this task
}
When I was trying to navigate from second to first viewcontroller..
I am using this code to navigate
-(IBAction)back
{
[self.navigationController popViewControllerAnimated:YES];
}
Here the problem arises...
The above orientation condition is not checked.. When I was trying to navigate from second to first view controller......
I don't know where I was lagging.... Whether I was stuck up with any logics or I want to change my code???????
call this method
-(void) viewWillAppear:(BOOL)animated{
[self willAnimateRotationToInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation duration:0];
}
-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown )
{
set frame here........
}
else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight )
{
set frame here........
}
}

present modal view on rotate

So I have a UITableViewControler displaying a tableview in portrait mode.
As soon as i rotate the iPhone i want to present a modal view in landscape mode.
In the tableView i use:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
And to handle the present the modal view:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration {
if((interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft))
{
NSLog(#"Push page view");
PagingViewController *s = [[PagingViewController alloc] initWithNibName:#"PagingView" bundle:nil];
s.hidesBottomBarWhenPushed = YES;
[self presentModalViewController:s animated:YES];
[s release];
}
}
The modal view i have the following:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
And to dismiss the modal view it self, I do:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration {
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
NSLog(#"Dismiss my self");
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
}
Some how this works two times.
The third time i rotate the iPhone from Portrait mode to Landscape mode, i get a bad access error.
I cant figure out what gives me the error.
Anyone care for a shot?
The simplest way I can think of is to implement -shouldAutorotate... and dismiss the modal view and return NO to abort rotation. Perhaps that will be sufficient to avoid any concurrency issues. If this suggestion isn't to your liking take a look at NSNotificationCenter.