¿La barra de estado de iOS 7 vuelve al estilo predeterminado de iOS 6 en la aplicación de iPhone?
En iOS 7, se UIStatusBar
ha diseñado de manera que se fusiona con la vista de esta manera:
(GUI diseñada por Tina Tavčar )
Es genial, pero arruinará un poco tu vista cuando tengas algo en la parte superior de la vista y se superponga con la barra de estado.
¿Existe una solución simple (como establecer una propiedad en info.plist) que pueda cambiar la forma en que funciona [sin superponerse] a como está en iOS6?
Sé que una solución más sencilla es tener
self.view.center.x
+ 20 puntos para cada controlador de vista, pero cambiarlos arruinará otras dimensiones (tener una diferenteself.view.center.x
puede causar problemas con las secuencias personalizadas, etc.) y de repente se convierte en un trabajo tedioso. lo mejor es evitarlo.Realmente me alegraría si alguien pudiera brindarme una solución sencilla para esto.
PD: Sé que puedo ocultar la barra de estado haciendo cosas como tener
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
En didFinishLaunchingWithOptions
método, pero esa es una solución alternativa, un atajo que evita el problema, así que no lo considero una solución real.
Esto es una publicación cruzada de una publicación de blog que escribí , pero aquí está el resumen completo de las barras de estado, barras de navegación y controladores de vista de contenedor en iOS 7:
No hay forma de conservar el diseño de la barra de estado al estilo de iOS 6. La barra de estado siempre se superpondrá a tu aplicación en iOS 7
No confunda la apariencia de la barra de estado con el diseño de la barra de estado. La apariencia (clara o predeterminada) no afecta la forma en que se presenta la barra de estado (marco/altura/superposición). Es importante tener en cuenta también que la barra de estado del sistema ya no tiene ningún color de fondo. Cuando la API hace referencia a UIStatusBarStyleLightContent, se refiere a texto blanco sobre un fondo claro. UIStatusBarStyleDefault es texto negro sobre un fondo claro.
La apariencia de la barra de estado se controla a lo largo de una de dos rutas básicas mutuamente excluyentes: puede configurarlas mediante programación de la manera tradicional o UIKit actualizará la apariencia según algunas propiedades nuevas de UIViewController. La última opción está activada de forma predeterminada. Verifique el valor plist de su aplicación para "Apariencia de la barra de estado basada en ViewController" para ver cuál está usando. Si establece este valor en YES, cada controlador de vista de nivel superior en su aplicación (que no sea un controlador de vista de contenedor UIKit estándar) debe anular el estilo preferidoStatusBarStyle y devolver el estilo predeterminado o el estilo claro. Si edita el valor de plist a NO, podrá administrar la apariencia de la barra de estado utilizando los métodos familiares de UIApplication.
UINavigationController alterará la altura de su UINavigationBar a 44 puntos o 64 puntos, dependiendo de un conjunto de restricciones bastante extraño e indocumentado. Si UINavigationController detecta que la parte superior del marco de su vista es visualmente contigua a la parte superior de su UIWindow, entonces dibuja su barra de navegación con una altura de 64 puntos. Si la parte superior de su vista no es contigua a la parte superior de UIWindow (incluso si está separada por solo un punto), entonces dibuja su barra de navegación de la forma "tradicional" con una altura de 44 puntos. UINavigationController realiza esta lógica incluso si hay varios elementos secundarios dentro de la jerarquía del controlador de vista de su aplicación. No hay forma de prevenir este comportamiento.
Si proporciona una imagen de fondo de barra de navegación personalizada que tiene solo 44 puntos (88 píxeles) de alto y los límites de la vista de UINavigationController coinciden con los límites de UIWindow (como se explica en el punto 4), UINavigationController dibujará su imagen en el marco (0,20,320 ,44), dejando 20 puntos de espacio negro opaco encima de su imagen personalizada. Esto puede confundirlo haciéndole pensar que es un desarrollador inteligente que pasó por alto la regla número 1, pero está equivocado. La barra de navegación todavía tiene 64 puntos de altura. Incrustar un UINavigationController en una jerarquía de vista de estilo de deslizar para revelar deja esto muy claro.
Tenga cuidado con la propiedad edgeForExtendedLayout de UIViewController, con un nombre confuso. Ajustar bordesForExtendedLayout no hace nada en la mayoría de los casos. La única forma en que UIKit usa esta propiedad es si agrega un controlador de vista a UINavigationController, luego UINavigationController usa bordesForExtendedLayout para determinar si su controlador de vista secundario debe ser visible debajo del área de la barra de navegación/barra de estado. Configurar bordesForExtendedLayout en UINavigationController no modifica si UINavigationController tiene o no un área de barra de navegación de 44 o 64 puntos de altura. Consulte el n.° 4 para conocer esa lógica. Se aplica una lógica de diseño similar a la parte inferior de la vista cuando se utiliza una barra de herramientas o UITabBarController.
Si todo lo que intenta hacer es evitar que su controlador de vista infantil personalizado se superponga a la barra de navegación cuando está dentro de un UINavigationController, entonces configure bordesForExtendedLayout en UIRectEdgeNone (o al menos una máscara que excluya UIRectEdgeTop). Establezca este valor lo antes posible en el ciclo de vida de su controlador de vista.
UINavigationController y UITabBarController también intentarán rellenar los contentInsets de las vistas de tabla y de colección en su jerarquía de subvistas. Lo hace de manera similar a la lógica de la barra de estado del n.° 4. Existe una forma programática de evitar esto, configurando automáticamenteAdjustsScrollViewInsets en NO para sus vistas de tabla y vistas de colección (el valor predeterminado es SÍ). Esto planteó algunos problemas serios para Whisper y Riposte, ya que utilizamos ajustes de contentInset para controlar el diseño de las vistas de tabla en respuesta a los movimientos de la barra de herramientas y del teclado.
Para reiterar: no hay forma de volver a la lógica de diseño de la barra de estado estilo iOS 6. Para aproximar esto, debe mover todos los controladores de vista de su aplicación a una vista de contenedor que esté desplazada 20 puntos desde la parte superior de la pantalla, dejando una vista intencionalmente negra detrás de la barra de estado para simular la apariencia anterior. Este es el método que terminamos usando en Riposte y Whisper.
Apple está presionando mucho para asegurarse de que no intentes hacer el punto 9. Quieren que rediseñemos todas nuestras aplicaciones para que se superpongan a la barra de estado. Sin embargo, existen muchos argumentos convincentes, tanto por razones técnicas como de experiencia del usuario, de por qué esto no siempre es una buena idea. Debes hacer lo que sea mejor para tus usuarios y no simplemente seguir los caprichos de la plataforma.
Actualizaciones el 19 de septiembre de 2013:
Se corrigieron errores de escala agregando
self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
errores tipográficos corregidos en la
NSNotificationCenter
declaración
Actualizaciones del 12 de septiembre de 2013:
corregido
UIViewControllerBasedStatusBarAppearance
aNO
Se agregó una solución para aplicaciones con rotación de pantalla.
Se agregó un enfoque para cambiar el color de fondo de la barra de estado.
Aparentemente, no hay forma de revertir la barra de estado de iOS7 a cómo funciona en iOS6.
Sin embargo, siempre podemos escribir algunos códigos y convertir la barra de estado en una similar a iOS6, y esta es la forma más corta que se me ocurre:
Establecer
UIViewControllerBasedStatusBarAppearance
en (para optar por que los controladoresNO
deinfo.plist
vista no ajusten el estilo de la barra de estado para que podamos configurar el estilo de la barra de estado mediante el método UIApplicationstatusBarStyle).En AppDelegate
application:didFinishLaunchingWithOptions
, llameif (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { [application setStatusBarStyle:UIStatusBarStyleLightContent]; self.window.clipsToBounds =YES; self.window.frame = CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20); //Added on 19th Sep 2013 self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height); } return YES;
con el fin de:
Comprueba si es iOS 7.
Configure el contenido de la barra de estado en blanco, a diferencia de UIStatusBarStyleDefault.
Evite que aparezcan subvistas cuyos marcos se extienden más allá de los límites visibles (para vistas que se animan en la vista principal desde arriba).
Cree la ilusión de que la barra de estado ocupa espacio como en iOS 6 cambiando y cambiando el tamaño del marco de la ventana de la aplicación.
Para aplicaciones con rotación de pantalla,
use NSNotificationCenter para detectar cambios de orientación agregando
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
y if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
crea un nuevo método en AppDelegate:
- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
int w = [[UIScreen mainScreen] bounds].size.width;
int h = [[UIScreen mainScreen] bounds].size.height;
switch(a){
case 4:
self.window.frame = CGRectMake(0,20,w,h);
break;
case 3:
self.window.frame = CGRectMake(-20,0,w-20,h+20);
break;
case 2:
self.window.frame = CGRectMake(0,-20,w,h);
break;
case 1:
self.window.frame = CGRectMake(20,0,w-20,h+20);
}
}
De modo que cuando cambie la orientación, se activará una instrucción de cambio para detectar la orientación de la pantalla de la aplicación (vertical, boca abajo, horizontal izquierda o horizontal derecha) y cambiar el marco de la ventana de la aplicación respectivamente para crear la ilusión de la barra de estado de iOS 6.
Para cambiar el color de fondo de su barra de estado:
Agregar
@property (retain, nonatomic) UIWindow *background;
para AppDelegate.h
crear background
una propiedad en su clase y evitar que ARC la desasigne. (No es necesario que lo haga si no está utilizando ARC).
Después de eso sólo necesitas crear la UIWindow en if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
:
background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];
¡No olvides hacerlo @synthesize background;
después @implementation AppDelegate
!
ACTUALIZACIÓN (NUEVA SOLUCIÓN)
Esta actualización es la mejor solución al problema de la barra de navegación de iOS 7. Puede configurar el color de la barra de navegación, por ejemplo: FakeNavBar.backgroundColor = [UIColor redColor];
Nota: si utiliza el controlador de navegación predeterminado, utilice la solución anterior.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
{
UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
FakeNavBar.backgroundColor = [UIColor whiteColor];
float navBarHeight = 20.0;
for (UIView *subView in self.window.subviews) {
if ([subView isKindOfClass:[UIScrollView class]]) {
subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
} else {
subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
}
}
[self.window addSubview:FakeNavBar];
}
return YES;
}
ANTIGUA SOLUCIÓN: SI usa el código anterior, ignore el siguiente código e imagen
Esta es una versión antigua de la solución de barra de navegación de iOS 7.
Resolví el problema con el siguiente código. Esto es para agregar una barra de estado. didFinishLaunchingWithOptions
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 320, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
[self.window.rootViewController.view addSubview:addStatusBar];
}
Y para Interface Builder esto es para cuando abres con iOS 6; está comenzando en 0 píxeles.