En iOS 7 si oculto la barra de estado con el método `prefersStatusBarHidden`, la barra de navigation se contrae / pierde altura. ¿Puedo detener este comportamiento?

En iOS 7, si utilizo el método prefersStatusBarHidden y devuelvo una variable de instancia que se puede cambiar:

 - (BOOL)prefersStatusBarHidden { return self.statusBarShouldBeHidden; } 

Y cambio la variable de instancia, ocultando así la barra de estado, la barra de navigation pierde el 20pt de altura que ocupa la barra de estado. No quiero esto, sin embargo. ¿Es posible ocultar la barra de estado pero mantener la altura de la barra de navigation ?

La barra de navigation mantiene su altura, es solo que la barra de navigation y la barra de estado no tienen ningún separador entre ellos (y tienen el mismo background), por lo que parecen ser una cosa, cuando, de hecho, son dos. Entonces, lo que realmente desea es que la barra de navigation se expanda para ocupar el espacio ocupado anteriormente tanto por la barra de navigation como por la barra de estado.

Lo he hecho así antes (heightCon es un IBOutlet a una restricción de altura en la barra de navigation).

 -(IBAction)hideStatusBar:(id)sender { static BOOL hidden = YES; [[UIApplication shanetworkingApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide]; self.heightCon.constant = (hidden)? 64 : 44; [UIView animateWithDuration:0.35 animations:^{ [self.navBar layoutIfNeeded]; }]; hidden = ! hidden; } 

Encontré una solución a este problema en la siguiente input de blog: http://www.factorialcomplexity.com/blog/2014/08/05/fixed-height-navigation-bar-on-ios7.html, pero su solución utiliza un método swizzling en UINavigationBar, que me parece poco atractivo.

ACTUALIZAR:

Me di count de que subclasificar UINavigationBar y proporcionar una implementación similar a la solución swizzled resuelve este problema (Swift aquí, pero funciona igual en Obj-C):

 class MyNavigationBar: UINavigationBar { override func sizeThatFits(size: CGSize) -> CGSize { var size = super.sizeThatFits(size) if UIApplication.shanetworkingApplication().statusBarHidden { size.height = 64 } return size } } 

Luego actualiza la class de la barra de navigation en tu storyboard, o usa initWithNavigationBarClass:toolbarClass: cuando construyas tu controller de navigation para usar la nueva class.

No conseguí que la solución @rdelmar funcione para mí con NSLayoutConstraint pero utilicé su idea para elaborar este código tan simple.

 [[UIApplication shanetworkingApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; [UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ self.navigationBar.top = 20; } completion:nil]; 

Las options:UIViewAnimationOptionBeginFromCurrentState es muy importante aquí, de lo contrario, la animation es entrecortada porque comienza desde 0.