Paul T.
Paul T.

Reputation: 5038

setStatusBarOrientation issue

I have a navigation controller app. And first I push FirstViewController (support Portrait orientation) and then SecondViewController (supports all orientations). When I'm in landscape mode of SecondViewController and press back button, FirstViewController appears in landscape mode. That's why I manually rotate the navigation view, but when I want to set setStatusBarOrientation to Portrait (First view controller should appears only in portrait mode), the orientation of view controller is still landscape, and even if rotate the device to portrait mode, the orientation stay landscape .Here is my code of FirstViewController:

- (void)viewWillAppear:(BOOL)animated
{
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
    {
        if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
            prevInterfaceOrientation = UIInterfaceOrientationLandscapeLeft;
            self.navigationController.view.transform = CGAffineTransformIdentity;
            self.navigationController.view.transform =
            CGAffineTransformMakeRotation(degreesToRadians(90));
        }
        else if (self.interfaceOrientation ==
                 UIInterfaceOrientationLandscapeRight) {
            prevInterfaceOrientation = UIInterfaceOrientationLandscapeRight;
            self.navigationController.view.transform = CGAffineTransformIdentity;
            self.navigationController.view.transform =
            CGAffineTransformMakeRotation(degreesToRadians(-90));
        }
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
        [self.tableViewDetail reloadData];
    }


}

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

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{ 
    if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
    {
        if (prevInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
            self.navigationController.view.transform = CGAffineTransformIdentity;
        }
        else if (prevInterfaceOrientation ==
                 UIInterfaceOrientationLandscapeRight) {
            self.navigationController.view.transform = CGAffineTransformIdentity;
        }
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
        [self.tableViewDetail reloadData];
    }
}

I even tried to use:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    if (UIInterfaceOrientationIsLandscape(prevInterfaceOrientation))
    {
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
    }
}

but self.interfaceOrientation still stays landscape, when I rotate to portrait. But I really need to rotate the view to portrait mode manually to allow users to see,that FirstViewController suppors only portrait orientation. I have the option to put the SecondViewController's view on MainWindow (like modal window), but I don't like this idea, because if apple has setStatusBarOrientation method, it seems to me, that it has to be right solve of this issue.

Upvotes: 2

Views: 4714

Answers (3)

starea
starea

Reputation: 341

Another quick solution is

  1. Click on your project in the left side bar.
  2. In General settings, choose "Hide during application launch" option.

Upvotes: 0

Morten Holmgaard
Morten Holmgaard

Reputation: 7806

Steven Veltema's answer didn't work for me.

I had one view controller where all orientations where allowed, and the rest only supported portrait. When i had the first view controller in landscape and navigated to another view controller, the orientation didn't refresh as you are experiencing.

I found another trick to reload the views i correct orientation. Just add a modal view controller you don't even see it. Add this in all other views:

- (void)viewDidAppear:(BOOL)animated
{
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        UIViewController * viewController = [[UIViewController alloc] init];
        [self presentModalViewController:viewController animated:NO];
        [viewController dismissModalViewControllerAnimated:NO];
    }

    [super viewDidAppear:animated];
    ....
}

Upvotes: 0

Steven Veltema
Steven Veltema

Reputation: 2150

I would get rid of the transformations, and use

      [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:animated];

This in combination with the forced redrawing of the view stack will get it done. This can be done by adding the following to viewDidAppear to the first controller (it doesn't work in viewWillApear).

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

       UIWindow *window = [[UIApplication sharedApplication] keyWindow];
       if ([window.subviews count] > 0) {
           UIView *view = [window.subviews objectAtIndex:0];
           [view removeFromSuperview];
           [window insertSubview:view atIndex:0];
       }
       else {
           DLog(@"NO view to force rotate?");
       }

Unfortunately, the transition animation is not very clean when you do this, so I would recommend taking a snapshot of the portrait screen, overlay this over your view, and then fade it out with a separate animation.

Upvotes: 4

Related Questions