简体   繁体   中英

UINavigationController setViewControllers autorotation issue

I present a UINavigationController with two view controllers in stack and present the last view controller first. And tapping the back button obviously goes back to the first view controller.

    navCtrl = [[UINavigationController alloc] init];
    ViewController1 *vc1 = [[ViewController1 alloc] init];
    ViewController2* vc2 = [[ViewController2 alloc] init];

    [navCtrl setViewControllers:[NSArray arrayWithObjects:vc1, vc2, nil] animated:NO];
    [self presentViewController:navCtrl animated:YES completion:^{
    }];

The problem is that when I push the back button on the navigation controller in landscape mode, view controller vc1 frame is incorrect. The frame is (0,0,320,568) and is laid out in landscape mode. I am running iOS 7. The autorotation code is not invoked on pressing the back button.

Whereas, If I present the navigation controller with the natural order vc1,vc2, I don't see any issue.

EDIT: FYI, here are the -viewWillAppear and -viewDidAppear calls in vc1 :

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

    self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];
    [[UIApplication sharedApplication] setStatusBarHidden:NO
                                            withAnimation:UIStatusBarAnimationNone];

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];

    NSLog(@"Frame = %@", NSStringFromCGRect(self.view.frame));
}

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

    // Get status bar height if visible
    if (![UIApplication sharedApplication].statusBarHidden) {
        CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
        CGFloat statusBarHeight = MIN(statusBarFrame.size.height, statusBarFrame.size.width);

        // Set navigation bar frame
        CGRect navBarFrame = self.navigationController.navigationBar.frame;

        [self.navigationController setNavigationBarHidden:YES animated:NO];
        [self.navigationController setNavigationBarHidden:NO animated:NO];
        /*
        navBarFrame.origin.y = statusBarHeight;
        self.navigationController.navigationBar.frame = navBarFrame;
        */
        UIEdgeInsets e = UIEdgeInsetsMake(statusBarHeight + navBarFrame.size.height, 0, navBarFrame.size.height + 12, 0);
        [_tableView setScrollIndicatorInsets:e];
        [_tableView setContentInset:e];
    }

    _tableView.rowHeight = 75;

    self.spinner = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
    spinner.frame = CGRectMake(145, 200, 30, 30);
    [self.view addSubview:spinner];

    [spinner startAnimating];

    [self performSelector:@selector(refreshData) withObject:nil afterDelay:0.f];
}

I found the problem. For some old iOS bug workaround which I don't remember I had the following line in viewDidLoad

[self.navigationController.view setFrame: [self.navigationController.view bounds]];

There are a few things you need to check here:


You said you already checked, but lets be safe - check the Auto-Resizing on the view.


Do your view controllers implement the following method?

- (NSUInteger)supportedInterfaceOrientations;

Are you presenting the navigation controller as a child view controller? When doing that make sure the following method is returning its default YES

- (BOOL)shouldAutomaticallyForwardRotationMethods;

Check you are not adding child view controllers to the view of a UINavigationController as it doesn't forward the appearance methods, its best to handle that from within the view controllers on the navigation controller.


Failing all of the above you should put a breakpoint in viewWillAppear of vc1 and check its frame, if the frame is correct, but the navigationContoller.view frame is incorrect then you must check your auto-resizing masks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM