La barra de estado y la barra de navegación aparecen sobre los límites de mi vista en iOS 7

Hace poco descargué Xcode 5 DP para probar mis aplicaciones en iOS 7. Lo primero que noté y confirmé es que los límites de mi vista no siempre se ajustan a la cuenta para la barra de estado y la barra de navegación.

En viewDidLayoutSubviews , viewDidLayoutSubviews los límites de la vista:

{{0, 0}, {320, 568}}

Esto hace que mi contenido aparezca debajo de la barra de navegación y la barra de estado.

Sé que podría explicar la altura yo mismo obteniendo la altura de la pantalla principal, restando la altura de la barra de estado y la altura de la barra de navegación, pero eso parece un trabajo extra innecesario.

¿Cómo puedo solucionar este problema?

Actualizar:

Encontré una solución para este problema específico. Establezca la propiedad translúcida de la barra de navegación en NO:

 self.navigationController.navigationBar.translucent = NO; 

Esto arreglará la vista al enmarcarse debajo de la barra de navegación y la barra de estado.

Sin embargo, no encontré una solución para el caso cuando desea que la barra de navegación sea translúcida. Por ejemplo, al ver una foto en pantalla completa, deseo que la barra de navegación sea translúcida y que la vista se enmarque debajo de ella. Eso funciona, pero cuando alterno mostrando u ocultando la barra de navegación, he experimentado resultados aún más extraños. La primera subvista (un UIScrollView) obtiene sus límites y su origen cambia cada vez.

Puede lograrlo implementando una nueva propiedad llamada edgesForExtendedLayout en iOS7 SDK. Por favor agregue el siguiente código para lograr esto,

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; 

Necesita agregar lo anterior en su método -(void)viewDidLoad .

iOS 7 trae varios cambios a la forma de diseñar y personalizar el aspecto de su interfaz de usuario . Los cambios en el diseño del controlador de vista, el color del tinte y la fuente afectan a todos los objetos UIKit en su aplicación. Además, las mejoras en las API del reconocedor de gestos le brindan un control más detallado sobre las interacciones de gestos.

Usando View Controllers

En iOS 7, los controladores de visualización usan diseño de pantalla completa. Al mismo tiempo, iOS 7 le brinda un control más granular sobre la forma en que un controlador de vista establece sus vistas. En particular, el concepto de diseño de pantalla completa se ha refinado para permitir que un controlador de vista especifique el diseño de cada borde de su vista.

La propiedad del controlador de vista wantsFullScreenLayout está en desuso en iOS 7. Si actualmente especifica wantsFullScreenLayout = NO , el controlador de vista puede mostrar su contenido en una ubicación de pantalla inesperada cuando se ejecuta en iOS 7.

Para ajustar cómo un controlador de vista establece sus vistas, UIViewController proporciona las siguientes propiedades:

  • edgesForExtendedLayout

La propiedad edgesForExtendedLayout utiliza el tipo UIRectEdge , que especifica cada uno de los cuatro bordes de un rectángulo, además de especificar none y all. Utilice edgesForExtendedLayout para especificar qué bordes de una vista deben extenderse, independientemente de la translucidez de la barra. De forma predeterminada, el valor de esta propiedad es UIRectEdgeAll .

  • extendedLayoutIncludesOpaqueBars

Si su diseño usa barras opacas, refine edgesForExtendedLayout estableciendo también la propiedad extendedLayoutIncludesOpaqueBars en NO . (El valor predeterminado de extendedLayoutIncludesOpaqueBars es NO ).

  • Ajusta automáticamenteScrollViewInsets

Si no desea que las inserciones de contenido de una vista de desplazamiento se ajusten automáticamente, configure automaticallyAdjustsScrollViewInsets AjustaScrollViewInsets a NO . (El valor predeterminado de automaticallyAdjustsScrollViewInsets es ).

  • topLayoutGuide, bottomLayoutGuide

Las propiedades topLayoutGuide y bottomLayoutGuide indican la ubicación de los bordes de la barra superior o inferior en la vista de un controlador de vista. Si las barras se superponen en la parte superior o inferior de una vista, puede usar Interface Builder para posicionar la vista relativa a la barra creando restricciones en la parte inferior de topLayoutGuide o en la parte superior de bottomLayoutGuide. (Si no hay barras que se superpongan a la vista, la parte inferior de topLayoutGuide es la misma que la parte superior de la vista y la parte superior de bottomLayoutGuide es la misma que la parte inferior de la vista). Ambas propiedades se crean de forma perezosa cuando se solicita.

Por favor, consulte, Apple Doc

No tiene que calcular qué tan lejos se puede cambiar todo, hay una construcción en propiedad para esto. En Interface Builder, resalte su controlador de vista y luego navegue hasta el inspector de atributos. Aquí verá algunas casillas de verificación junto a las palabras “Extender bordes”. Como puede ver, en la primera captura de pantalla, la selección predeterminada es para que el contenido aparezca debajo de las barras superior e inferior, pero no debajo de las barras opacas, que es la razón por la que configurar el estilo de barra no translúcido funcionó para usted.

Como puede ver en la primera captura de pantalla, hay dos elementos de UI escondidos debajo de la barra de navegación. (He habilitado wireframes en IB para ilustrar esto) Estos elementos, un UIButton y un UISegmentedControl tienen su origen “y” establecido en cero, y el controlador de vista está configurado para permitir el contenido debajo de la barra superior.

enter image description here

Esta segunda captura de pantalla muestra lo que ocurre cuando deselecciona la checkbox “En las barras superiores”. Como puede ver, la vista de los controladores de vista se ha desplazado hacia abajo de forma adecuada para que su origen esté justo debajo de la barra de navegación.

enter image description here

Esto también se puede lograr programáticamente mediante el uso de -[UIViewController edgesForExtendedLayout] . Aquí hay un enlace a la referencia de clase para edgeForExtendedLayout , y para UIRectEdge

 [self setEdgesForExtendedLayout:UIRectEdgeNone]; 

Creé mi vista programáticamente y esto terminó trabajando para mí:

 - (void) viewDidLayoutSubviews { // only works for iOS 7+ if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar (iOS 6 style) viewBounds.origin.y = topBarOffset * -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1); self.view.bounds = viewBounds; } } 

Fuente (en la sección superiorLayoutGuide en la parte inferior de la página 39).

Solución Swift 3 / Swift 4 que también funciona con archivos NIB / XIB en iOS 10+:

 override func viewDidLoad() { super.viewDidLoad() edgesForExtendedLayout = [] } 

Si desea que la vista tenga la barra de navegación translúcida (que es agradable), debe configurar un contentInset o similar.

Así es como lo hago:

 // Check if we are running on ios7 if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) { CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame]; float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height; myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0); } 

edgesForExtendedLayout es el truco para iOS 7. Sin embargo, si edgesForExtendedLayout la aplicación en iOS 7 SDK y la implementa en iOS 6, la barra de navegación aparece translúcida y las vistas van por debajo. Por lo tanto, para solucionarlo tanto para iOS 7 como para iOS 6, haga lo siguiente:

 self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque; if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; // iOS 7 specific 

En su archivo plist de aplicaciones, agregue una fila, llámelo “Ver apariencia de la barra de estado basada en el controlador” y configúrelo en NO .

El truco más simple es abrir el archivo NIB y hacer estos dos sencillos pasos:

  1. Simplemente alternar y configurarlo a la que prefiera:

Ingrese la descripción de la imagen aquí

  1. Seleccione los UIView’s / UIIMageView’s / … que desea mover hacia abajo. En mi caso, solo se superpuso el logotipo y establecí el delta en +15; (O -15 si elige iOS 7 en el paso 1)

Ingrese la descripción de la imagen aquí

Y el resultado :

antes deDespués

Solución Swift:

 override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.edgesForExtendedLayout = UIRectEdge.None } 

Me gustaría ampliar la respuesta de Stunner y agregar una statement if para verificar si es iOS-7, porque cuando lo probé en iOS 6 mi aplicación se bloqueó.

La adición sería agregar:

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 

Así que sugeriría agregar este método a su archivo MyViewControler.m :

 - (void) viewDidLayoutSubviews { if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; viewBounds.origin.y = topBarOffset * -1; self.view.bounds = viewBounds; } } 

Swift 3

 override func viewWillAppear(_ animated: Bool) { self.edgesForExtendedLayout = [] } 

Tengo un escenario en el que uso el BannerViewController escrito por Apple para mostrar mis anuncios y un ScrollViewController incrustado en el BannerViewController.

Para evitar que la barra de navegación ocultara mi contenido, tuve que hacer dos cambios.

1) Modificar BannerViewController.m

 - (void)viewDidLoad { [super viewDidLoad]; float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; if (systemVersion >= 7.0) { self.edgesForExtendedLayout = UIRectEdgeNone; } } 

2) Modificar mi ScrollViewContoller

 - (void)viewDidLoad { [super viewDidLoad]; float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; if (systemVersion >= 7.0) { self.edgesForExtendedLayout = UIRectEdgeBottom; } } 

Ahora los anuncios se muestran correctamente en la parte inferior de la vista en lugar de estar cubiertos por la barra de navegación y el contenido en la parte superior no se corta.

simplemente configure el siguiente código en vista aparecerá.

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) { self.edgesForExtendedLayout = UIRectEdgeNone; } 

hacer una restricción al diseño superior como este enter image description here

Para mí, la solución más simple es agregar dos claves en el plist

enter image description here

Agregue la clave “Ver apariencia de la barra de estado basada en el controlador” de la lista desplegable como una fila en info.plist . Algo como esto:

Ingrese la descripción de la imagen aquí

Tuve el mismo problema con mi aplicación por iPads (armv7, armv7s, amr64) solo al presentar otro UIViewController y después de descartarlos, se pasó a la barra de navegación en la barra de estado … Dedico mucho tiempo a encontrar una solución para eso. Estoy usando storyboard y en InterfaceBuilder para UIViewController, lo que hace terrible establecer la presentación desde FullScreen -> Current Context y soluciona este problema. Funciona en mi aplicación solo para iPads => iOS8.0 (probando con iOS8.1) y para iPads con iOS 7.1 ¡no funciona! ver captura de pantalla

Pasos para Ocultar la barra de estado en iOS 7:

1. Vaya a su archivo info.plist de la aplicación.

2.Y establecer, ver la apariencia de la barra de estado basada en el controlador: booleana NO

Espero haber resuelto el problema de la barra de estado …..

En mi caso, interrumpir loadView ()
este código: self.edgesForExtendedLayout = UIRectEdgeNone

pero después de eliminar loadView () todo funcionó bien

Swift 4.2 – Xcode 10.0 – iOS 12.0:

 if #available(iOS 11.0, *) {} else { self.edgesForExtendedLayout = [] self.navigationController?.view.backgroundColor = .white }