Forma correcta para ocultar la barra de estado de iOS, con la animación y el tamaño de la raíz de vista

Considerar una vista controlador que necesita para deslizar (o esconder) de la barra de estado cuando hace clic en un botón.

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

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

Lo que se espera es la raíz de vista para ampliar el espacio que anteriormente era utilizado por la barra de estado (de animación, con la misma duración que la barra de estado de la animación).

¿Cuál es la forma correcta de hacerlo?

(Soy consciente de que hay un montón de preguntas similares, pero yo no podía encontrar nada acerca de cómo ocultar la barra de estado en la demanda y no en la clandestinidad para mostrar un nuevo punto de vista controlador)

La «fuerza bruta» enfoque

Obviamente, las siguientes obras…

[[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 sus desventajas:

  • Hardcodes la duración de la animación de diapositivas
  • Hardcodes la altura de la barra de estado
  • La raíz de la vista de origen queda en (0,-20). Me gusta que mis cuadros para iniciar en (0,0) siempre que sea posible.

Lo que ya he probado

  • A asegurarse de que las autoresize máscara de la raíz de vista ha UIViewAutoresizingFlexibleTopMargin y UIViewAutoresizingFlexibleHeight.
  • Llamado [self.view setNeedsLayout] después de ocultar la barra de estado.
  • Llamado [self.view setNeedsDisplay] después de ocultar la barra de estado.
  • Conjunto wantsFullScreenLayout a YES antes y después de ocultar la barra de estado.
InformationsquelleAutor hpique | 2012-11-29

7 Kommentare

  1. 15

    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);
    }];
    • Gracias @Lefteris. Se mira esto dentro de poco. Sin embargo, no codificar la animación duración.
    • AFAIK, no hay manera de obtener el estado de la barra de animación duración. Usted puede conseguir el Teclado de animación duración, mediante la suscripción del teclado willshow/willhide notificaciones, pero no para el UIStatusBar. También parece ser un bug en iOS desde edades que nunca es fija, y la UIApplicationDidChangeStatusBarFramenotification/UIApplicationWillChangeStatusBarframenotification no ser despedido cuando la barra de estado se oculta o muestra…
    • Hola.. tengo tabbar aplicación con Dos pestañas. Quiero ocultar 2º pestañas de la barra de estado solo,pero si hago eso, mi primer pestañas de la barra de estado también se esconden. ¿Cómo puedo solucionar?
    • sólo hay 1 barra de estado por la ventana, lo que significa que también por la aplicación.
    • no trabaja para anidada de los controladores. pero es un buen enfoque. también funciona para hacer esto: auto.vista.de la ventana.altura += statusBarHiddenState ? -20 : 20; (si el controlador gestiona el statusbar (barra de estado). sigue teniendo problemas con el hijo de los controladores.
    • Me di cuenta de que la setStatusBarHidden método sólo funciona cuando se establece el «controlador de Vista basados en la barra de estado de la apariencia» a NO en su -info.plist. De lo contrario, no tiene ningún efecto (iOS 8).
    • Bueno, sí. Otra cosa es pedir el controlador de vista de si se debe ocultar la barra de estado o no a través de la - (BOOL)prefersStatusBarHidden método de delegado.
    • El código es en realidad fuera de fecha. Los recomendados y probados enfoque es de @awfulcode

  2. 25

    Para aquellos que están tratando de implementar este con vista controlador basado en la apariencia de la barra de estado, que necesita para implementar la prefersStatusBarHidden método en el controlador de vista de

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

    Y a continuación, en el botón haga clic en el método:

    - (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 la animación, utilice esto:

    -(UIStatusBarAnimation)preferredStatusBarUpdateAnimation
    {
        return UIStatusBarAnimationSlide;
    }

    Y para personalizar el estilo:

    - (UIStatusBarStyle)preferredStatusBarStyle
    {
        return UIStatusBarStyleLightContent;
    }
    • Gracias man.. Funciona perfecto
    • Esto es lo que se necesita hacer para iOS 9+
    • eso es perfecto! gracias
    • Recomendados y probados enfoque. Gracias!
  3. 8

    Puede presentar y despedir modal de controlador de vista de 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];
    }

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

    • Gran. Funciona. No sé por qué, aunque. Parece un simple hack.
    • Este es el infierno de un hack… que funciona muy bien 🙂
  4. 7

    Ocultar o Mostrar la barra de estado que también modifica 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];
     }
    • Esta es una respuesta mejor.
    • gran respuesta!!!
  5. 1

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

    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
    }
  6. 0

    Sé un paseo alrededor de este, pero las desventajas que también es obvio. Puede establecer self.wantsFullScreenLayout = YES; en su viewDidLoad y establecer su xib archivo tan grande como la pantalla(320×480, y 320×568 para iPhone5). Pero esto significa que el área bajo la barra de estado no es también visible. Y usando de esta manera su punto de vista también que no se expanda al ocultar la barra de estado. Se puede considerar que esta forma si usted no tiene algo para mostrar en la barra de estado área.

    • wantsFullScreenLayout está en desuso en iOS 7
  7. 0

    Después de pasar horas de experimento y la búsqueda de la respuesta; en particular esta respuesta. Con un poco de ajuste, he logrado hacer, ahora la parte superior de la brecha de 20px se ha ido entre la transición!

    Supongamos que tenemos un BOOL isStatusBarEnabled ivar, que nos indicará si debemos tener la barra de estado ocultos o no, (por ejemplo: al acceder a NSUserDefault para la comprobación de boolValueForKey).

    Así, en primer lugar comprobar para saber si la barra de estado ya está oculta o no a través de [[UIApplication sharedApplication] isStatusBarHidden], si no está oculto (== se muestra), lo ocultamos! Otra cosa, hacer otra cosa!

    • Para solucionar 20px cuando se muestra el estado – pero la navegación no está correctamente empujado hacia abajo, sólo tiene que añadir de 20 puntos a origin.y de self.navgigationController.navigationBar.frame.

    • Hacer lo mismo cuando se quiere ocultar la barra de estado, sólo quita de 20 puntos a origin.y de self.navgigationController.navigationBar.frame así que acaba de salir de 0.

    esto es!

    @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 clave para permitir al usuario elegir 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];
    
      }
    
      //...
    }

    que es!

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...