transparente superior quitar para ocultar estado desaparece como barra iphone ios uiviewcontroller statusbar uistatusbar

iphone - superior - La forma correcta de ocultar la barra de estado en iOS, con la animación y el cambio de tamaño de la vista raíz



dock transparente en ios 11 (7)

Considere un controlador de vista que necesita deslizar hacia afuera (u ocultar) la barra de estado cuando se hace clic en un botón.

- (void) buttonClick:(id)sender { [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; }

Lo anterior oculta efectivamente la barra de estado, pero no cambia el tamaño de la vista raíz de forma adecuada, dejando un espacio de 20 píxeles en la parte superior.

Lo que esperaba era que la vista raíz se expandiera sobre el espacio que previamente usaba la barra de estado (animada, con la misma duración que la animación de la barra de estado).

¿Cuál es la forma correcta de hacer esto?

(Soy consciente de que hay muchas preguntas similares, pero no pude encontrar ninguna sobre ocultar la barra de estado bajo demanda en lugar de ocultarla para mostrar un nuevo controlador de vista)

El enfoque de la "fuerza bruta"

Obviamente, los siguientes trabajos ...

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; [UIView animateWithDuration:0.25 animations:^{ CGRect frame = self.view.frame; frame.origin.y -= 20; frame.size.height += 20; self.view.frame = frame; }];

... pero tiene desventajas:

  • Codifica la duración de la animación de diapositivas
  • Códigos duros de la altura de la barra de estado
  • El origen de la vista raíz permanece en (0, -20). Me gusta que mis cuadros comiencen en (0,0) siempre que sea posible.

Lo que ya probé

  • Se aseguró de que la máscara de autoevaluación de la vista raíz tenga UIViewAutoresizingFlexibleTopMargin y UIViewAutoresizingFlexibleHeight .
  • Se llama [self.view setNeedsLayout] después de ocultar la barra de estado.
  • Se llama [self.view setNeedsDisplay] después de ocultar la barra de estado.
  • Establezca wantsFullScreenLayout en YES antes y después de ocultar la barra de estado.

Conozco un camino para esto pero las desventajas también son obvias. Puede establecer self.wantsFullScreenLayout = YES; en su viewDidLoad y configure su archivo xib tan grande como la pantalla (320x480 y 320x568 para iPhone5). Pero esto significa que el área debajo de la barra de estado tampoco es visible. Y al usar de esta manera, su vista tampoco se expandirá cuando oculte la barra de estado. Puede considerarlo de esta manera si no tiene algo que mostrar en el área de la barra de estado.


Después de pasar horas experimentando y buscando respuestas; particularmente esta respuesta . Con un poco de ajuste, lo he logrado con éxito, ¡ahora el espacio más alto, 20px, se ha ido entre la transición!

Supongamos que tenemos un BOOL isStatusBarEnabled ivar que indicará si deberíamos tener la barra de estado oculta o no (por ejemplo, al acceder a NSUserDefault para verificar boolValueForKey ).

Entonces, primero verificamos si si statusBar ya está oculto o no a través de [[UIApplication sharedApplication] isStatusBarHidden] , si no está oculto (== se muestra), lo ocultamos! De lo contrario, ¡haz lo contrario!

  • Para corregir 20px cuando se muestra el estado, pero la navegación no está correctamente presionada, simplemente agregue 20 puntos al origin.y de self.navgigationController.navigationBar.frame .

  • Haz lo mismo cuando queremos ocultar la barra de estado, simplemente elimina esos 20 puntos de origin.y de self.navgigationController.navigationBar.frame así que simplemente déjalo 0 .

¡eso es todo!

@implementation SomeViewController { BOOL isStatusBarEnabled; } // ... - (void)toggleStatusBar { UINavigationBar *navBar = self.navigationController.navigationBar; if ([[UIApplication sharedApplication] isStatusBarHidden]) { // Change to regular mode // Show status bar [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide]; [UIView animateWithDuration:0.3 animations:^{ navBar.frame = CGRectMake(navBar.frame.origin.x, 20, navBar.frame.size.width, navBar.frame.size.height); } completion:nil]; } else if (![[UIApplication sharedApplication] isStatusBarHidden]) { // Change to fullscreen mode // Hide status bar [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; [UIView animateWithDuration:0.4 animations:^{ navBar.frame = CGRectMake(navBar.frame.origin.x, 0, navBar.frame.size.width, navBar.frame.size.height); } completion:nil]; } } // ...

... entonces, en mi caso, tengo una tecla de configuración para que el usuario elija alternar mostrar / ocultar la barra de estado.

// ... - (void)onDefaultsChanged:(NSNotification*)aNotification { NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults]; isStatusBarEnabled = [standardDefaults boolForKey:kStatusBar]; if (isStatusBarEnabled) { if ([[UIApplication sharedApplication] isStatusBarHidden]) { // Change to regular mode // Show status bar [self toggleStatusBar]; } else { // Change to fullscreen mode // Hide status bar [self toggleStatusBar]; } // ... }

¡Eso es!


Esto funciona bien y no tiene nada codificado .

CGRect appFrame = [[UIScreen mainScreen] applicationFrame]; [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; [UIView animateWithDuration:0.25 animations:^{ self.navigationController.navigationBar.frame = self.navigationController.navigationBar.bounds; self.view.window.frame = CGRectMake(0, 0, appFrame.size.width, appFrame.size.height); }];


Ocultar o Mostrar barra de estado que también reajusta el tamaño de la vista:

-(void)statusBar:(BOOL)status { UIViewController *rootViewController = self.view.window.rootViewController; UIView *view = rootViewController.view; // Hide/Unhide the status bar [[UIApplication sharedApplication] setStatusBarHidden:status]; // BOOL : YES or NO // statusBar frame CGRect statusBarFrame = [UIApplication.sharedApplication statusBarFrame]; // Establish baseline frame CGRect newViewFrame = self.view.window.bounds; // Check statusBar frame is worth dodging if (!CGRectEqualToRect(statusBarFrame, CGRectZero)) { UIInterfaceOrientation currentOrientation = rootViewController.interfaceOrientation; if (UIInterfaceOrientationIsPortrait(currentOrientation)) { // If portrait need to shrink height newViewFrame.size.height -= statusBarFrame.size.height; if (currentOrientation == UIInterfaceOrientationPortrait) { // If not upside-down move down origin newViewFrame.origin.y += statusBarFrame.size.height; } } else { // Is landscape // portrait shrink width newViewFrame.size.width -= statusBarFrame.size.width; if (currentOrientation == UIInterfaceOrientationLandscapeLeft) { // If the status bar is on the left side of the window move origin newViewFrame.origin.x += statusBarFrame.size.width; } } } view.frame = newViewFrame; // pass new frame }

método de llamada (mensaje):

if ([[UIApplication sharedApplication] isStatusBarHidden]) { [self statusBar:NO]; } else { [self statusBar:YES]; }


Para aquellos que están intentando implementar esto con la apariencia de la barra de estado basada en el controlador de vista, debe implementar el método prefersStatusBarHidden en su controlador de vista

- (BOOL)prefersStatusBarHidden { // If self.statusBarHidden is TRUE, return YES. If FALSE, return NO. return (self.statusBarHidden) ? YES : NO; }

Y luego, en su método de clic de botón:

- (void) buttonClick:(id)sender { // Switch BOOL value self.statusBarHidden = (self.statusBarHidden) ? NO : YES; // Update the status bar [UIView animateWithDuration:0.25 animations:^{ [self setNeedsStatusBarAppearanceUpdate]; }]; }

Para establecer el estilo de animación, usa esto:

-(UIStatusBarAnimation)preferredStatusBarUpdateAnimation { return UIStatusBarAnimationSlide; }

Y para personalizar el estilo:

- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; }


Para mayor comodidad, una variante Swift 4 de la respuesta de @ awfulcode:

var statusBarHidden = false { didSet { UIView.animate(withDuration: 0.25) { self.setNeedsStatusBarAppearanceUpdate() } } } override var preferredStatusBarStyle: UIStatusBarStyle { return .default } override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return .fade } override var prefersStatusBarHidden: Bool { return statusBarHidden }


Puede presentar y luego cerrar el controlador de vista modal para ocultar la barra de estado correctamente

- (void)toggleStatusBar { BOOL isStatusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden]; [[UIApplication sharedApplication] setStatusBarHidden:!isStatusBarHidden]; UIViewController *vc = [[UIViewController alloc] init]; [self presentViewController:vc animated:NO completion:nil]; [self dismissViewControllerAnimated:NO completion:nil]; [vc release]; }

Usé este código en el método "willAnimateRotationToInterfaceOrientation" para orientación horizontal y todo está funcionando correctamente. Pero no sé si funcionará con la animación.