La barra de estado y la barra de navegación aparecen sobre los límites de mi vista en iOS 7
Recientemente 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 cambian de tamaño para tener en cuenta la barra de estado y la barra de navegación.
En viewDidLayoutSubviews
, imprimo los límites de la vista:
{{0, 0}, {320, 568}}
Esto hace que mi contenido aparezca debajo de la barra de navegación y de estado.
Sé que podría calcular 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 adicional innecesario.
¿Cómo puedo solucionar este problema?
Actualizar:
He encontrado 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 evitará que la vista quede enmarcada debajo de la barra de navegación y la barra de estado.
Sin embargo, no he encontrado una solución para el caso en el que 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 esté enmarcada debajo de ella. Eso funciona, pero cuando alterno entre mostrar/ocultar la barra de navegación, obtuve resultados aún más extraños. La primera subvista (una UIScrollView) cambia sus límites y origen cada vez.
Puede lograr esto implementando una nueva propiedad llamada edgesForExtendedLayout
en iOS7 SDK. Agregue el siguiente código para lograr esto,
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
Debe agregar lo anterior en su -(void)viewDidLoad
método.
iOS 7 trae varios cambios en la forma de diseñar y personalizar la apariencia 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 de reconocimiento de gestos le brindan un control más detallado sobre las interacciones de gestos.
Usando controladores de vista
En iOS 7, los controladores de visualización utilizan un 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 presenta sus vistas. En particular, el concepto de diseño de pantalla completa se ha perfeccionado para permitir que un controlador de vista especifique el diseño de cada borde de su vista.
La
wantsFullScreenLayout
propiedad del controlador de vista está obsoleta en iOS 7. Si actualmente especificawantsFullScreenLayout = 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 presenta sus vistas,
UIViewController
proporciona las siguientes propiedades:
- bordes para diseño extendido
La
edgesForExtendedLayout
propiedad utiliza elUIRectEdge
tipo, que especifica cada uno de los cuatro bordes de un rectángulo, además de especificar ninguno y todos. Se utilizaedgesForExtendedLayout
para especificar qué bordes de una vista deben extenderse, independientemente de la translucidez de la barra. De forma predeterminada, el valor de esta propiedad esUIRectEdgeAll
.
- diseño extendidoIncluye barras opacas
Si su diseño utiliza barras opacas, refine
edgesForExtendedLayout
estableciendo también laextendedLayoutIncludesOpaqueBars
propiedad en NO . (El valor predeterminado deextendedLayoutIncludesOpaqueBars
es NO ).
- automáticamenteAjustaDesplazamientoVistaInserciones
Si no desea que las inserciones de contenido de una vista de desplazamiento se ajusten automáticamente, configúrelo
automaticallyAdjustsScrollViewInsets
en NO . (El valor predeterminado deautomaticallyAdjustsScrollViewInsets
es SÍ ).
- guía de diseño superior, guía de diseño inferior
Las propiedades
topLayoutGuide
ybottomLayoutGuide
indican la ubicación de los bordes de la barra superior o inferior en la vista de un controlador de vista. Si las barras deben superponerse a la parte superior o inferior de una vista, puede usar Interface Builder para posicionar la vista en relación con la barra creando restricciones en la parte inferiortopLayoutGuide
o superior de bottomLayoutGuide. (Si ninguna barra debe superponerse a la vista, la parte inferiortopLayoutGuide
es la misma que la parte superior de la vista y la parte superiorbottomLayoutGuide
es la misma que la parte inferior de la vista). Ambas propiedades se crean de forma diferida cuando se solicita.
Consulte, documento de Apple
No es necesario calcular hasta qué punto bajar todo, hay una propiedad incorporada 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 que el contenido aparezca debajo de las barras superior e inferior, pero no debajo de las barras opacas, razón por la cual configurar el estilo de la barra para que no sea translúcido funcionó para usted.
Como puede ver en la primera captura de pantalla, hay dos elementos de la interfaz de usuario escondidos debajo de la barra de navegación. (He habilitado estructuras alámbricas 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 contenido debajo de la barra superior.
Esta segunda captura de pantalla muestra lo que sucede cuando desmarcas la casilla de verificación "Debajo de las barras superiores". Como puede ver, la vista de los controladores de vista se ha desplazado hacia abajo de manera adecuada para que su origen y esté justo debajo de la barra de navegación.
Esto también se puede lograr mediante programación 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 mediante programación y esto terminó funcionando 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 topLayoutGuide en la parte inferior de la página 39).