IOS Hiding and hiding the status bar Non-offset spy

I have a custom view controller that can contain two child controllers. The view of one of the controllers becomes visible when the device is in portrait orientation. The view of the other controller becomes visible when the device is in landscape orientation. However, when the landscape orientation view becomes visible, the status bar is retracted to make more space for the particular view. The status bar is turned off after the device returns to portrait mode. This custom view controller is displayed within the UINavigationController .

My problem is that my subtitles are not adjusted properly when changing the visibility of the status bar. As a result, you rotate the device in different directions, as shown in the figure below: enter image description here

As you can see, initially it is beautiful (in the portrait), but when the device is rotated, there is a white gap in which there was a status bar. When the device is rotated back to the portrait, the UINavigationController navigation bar rises and overlaps the status bar and a space appears between the navigation bar and the view below it. If you rotate 180 degrees very quickly from one landscape orientation to the opposite landscape orientation, the gap disappears and looks good.

The method below refers to a custom view controller and is called in willAnimateRotationToInterfaceOrientation:duration: (obviously for handling rotation events) and viewDidAppear: (for processing when viewing a view from a previous view controller in the navigation stack).

 - (void)cueAnimationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation fromViewDidAppear:(BOOL) fromViewDidAppear { // Fading animation during orientation flip. // Make sure its not already animating before trying. BOOL barHidden = [UIApplication sharedApplication].statusBarHidden; if (!isAnimating) { BOOL alreadyGoodGrid = (UIInterfaceOrientationIsLandscape(interfaceOrientation) && curView == self.gridViewController.view); BOOL alreadyGoodTable = (UIInterfaceOrientationIsPortrait(interfaceOrientation) && curView == self.tableViewController.view); if ((alreadyGoodGrid && barHidden) || (alreadyGoodTable && !barHidden)) { // If views are the way they should be for this orientation. Don't do // anything. return; } isAnimating = YES; UIView *nextView; // Get starting orientation. This will determine what view goes on top if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) nextView = self.gridViewController.view; else nextView = self.tableViewController.view; if (nextView == self.tableViewController.view) { if (!alreadyGoodTable) { self.tableViewController.view.alpha = 0.0; [self.view bringSubviewToFront:self.tableViewController.view]; } // Unhide the bar for the table view [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; } else // gridViewController { if (!alreadyGoodGrid) { self.gridViewController.view.alpha = 0.0; [self.view bringSubviewToFront:self.gridViewController.view]; } // Hide the bar for the grid view [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; } [UIView animateWithDuration:0.4 delay: 0.0 options: UIViewAnimationOptionAllowUserInteraction animations:^{ if (nextView == self.tableViewController.view) { self.tableViewController.view.alpha = 1.0; } else { self.gridViewController.view.alpha = 1.0; } } completion:^(BOOL finished) { if (nextView == self.tableViewController.view) { curView = self.tableViewController.view; } else { curView = self.gridViewController.view; } isAnimating = NO; }]; } } 

Many thanks to everyone who can take the time to look at this.

+4
source share
5 answers

Many people have a problem like mine, and there are other Q / A topics you should look for - I may have never found a magical answer. One of the troubles that you can try seems to “fix” the problem in some cases when you change the panel visibility to (re) display the status bar:

  • Hide the navigation bar.
  • Cancel hiding the status bar.
  • Hide the navigation bar.

Or Hide, Hide, Hide if you hide the status bar.

Sometimes people find that a little delay is required before Un-Hiding nav bar - so do this in the async send block to run in the next runloop. Sort of:

 dispatch_async(dispatch_get_main_queue(), ^{ [self.navigationController setNavigationBarHidden:NO animated:NO]; }); 
+2
source

After hours of work, I seem to have come up with some kind of solution. It seems to work flawlessly.

Here is my code:

 - (void)cueAnimationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation fromViewDidAppear:(BOOL) fromViewDidAppear { // Fading animation during orientation flip. // Make sure its not already animating before trying. BOOL barHidden = [UIApplication sharedApplication].statusBarHidden; if (!isAnimating) { BOOL alreadyGoodGrid = (UIInterfaceOrientationIsLandscape(interfaceOrientation) && curView == self.gridViewController.view); BOOL alreadyGoodTable = (UIInterfaceOrientationIsPortrait(interfaceOrientation) && curView == self.tableViewController.view); if ((alreadyGoodGrid && barHidden) || (alreadyGoodTable && !barHidden)) { // If views are the way they should be for this orientation. Don't do // anything. return; } isAnimating = YES; UIView *nextView; // Get starting orientation. This will determine what view goes on top if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) nextView = self.gridViewController.view; else nextView = self.tableViewController.view; if (nextView == self.tableViewController.view) { if (!alreadyGoodTable) { self.tableViewController.view.alpha = 0.0; [self.view bringSubviewToFront:self.tableViewController.view]; } [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; } else { if (!alreadyGoodGrid) { self.gridViewController.view.alpha = 0.0; [self.view bringSubviewToFront:self.gridViewController.view]; } [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; } [UIView animateWithDuration:0.4 delay: 0.0 options: UIViewAnimationOptionAllowUserInteraction animations:^{ CGRect r = self.navigationController.navigationBar.frame; if (nextView == self.tableViewController.view) { self.tableViewController.view.alpha = 1.0; self.navigationController.navigationBar.frame = CGRectMake(0.0, 20.0, r.size.width, r.size.height); self.view.frame = CGRectMake(0.0, 20.0, self.view.frame.size.width, self.view.frame.size.height - 20.0); } else { self.gridViewController.view.alpha = 1.0; self.navigationController.navigationBar.frame = CGRectMake(0.0, 0.0, r.size.width, r.size.height); double y = 0.0, h = 0.0; if (fromViewDidAppear) { y = -20.0; h = 20.0; } self.view.frame = CGRectMake(0.0, y, self.view.frame.size.width, self.view.frame.size.height + h); } } completion:^(BOOL finished) { if (nextView == self.tableViewController.view) { curView = self.tableViewController.view; } else { curView = self.gridViewController.view; } isAnimating = NO; }]; } } 

What I am doing is checking if the method is called from viewDidAppear: or somewhere else (in this case only willAnimateRotationToInterfaceOrientation:duration: . Things behave differently depending on who calls the method. In any case, I configure self.view.frame and self.navigationController.navigationBar.frame to account for differences in the location of the status bar. When we exit viewDidAppear: I need to set a negative value y for the height of the status bar in order to get the subview to rise correctly. Everything seems to work pretty well.

0
source

I had the same issue when the status bar and navigation bar overlapped after they were hidden and then shown again. I found a solution on github here (see the showUI method), which I changed to suit my needs.

 - (void)toggleNavBar:(BOOL)hide { navBarHidden = hide; //Fade status bar [[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationFade]; //Fade navigation bar [UINavigationBar beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.3]; // Approximately the same time the status bar takes to fade. self.navigationController.navigationBar.alpha = hide ? 0 : 1; [UINavigationBar commitAnimations]; // Being invisible messes with the position of the navigation bar, every time it gets // visible we need to set it to the correct y-offset (just below the status bar) [self adjustNavBarOrigin]; } -(void)adjustNavBarOrigin { CGRect r = self.navigationController.navigationBar.frame; r.origin.y = 20; //Height of the statusbar, can't find a reliable method in the SDK to get this value self.navigationController.navigationBar.frame = r; } 
0
source

for ios7, override prefersStatusBarHidden

 - (BOOL)prefersStatusBarHidden { return NO if landscape and NO if landscape; } 

when changing orientation, call the function below to call the prefersStatusBarHidden function

 [self setNeedsStatusBarAppearanceUpdate]; 

see detailed answer at fooobar.com/questions/446912 / ...

0
source

This solved my problem:

 self.automaticallyAdjustsScrollViewInsets = false 
0
source

All Articles