Explicación de la diferencia entre automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout en iOS7

He estado leyendo mucho acerca de la transición de iOS IU.

No puedo get lo que estas tres properties automaticallyAdjustsScrollViewInsets edgesForExtendedLayout , extendedLayoutIncludesOpaqueBars , edgesForExtendedLayout ??

Por ejemplo, estoy tratando de hacer que mis controlleres de vista comiencen debajo de la barra de estado, pero no puedo lograrlo.

A partir de iOS7, los controlleres de vista utilizan el layout de pantalla completa de forma pnetworkingeterminada. Al mismo time, tiene más control sobre cómo expone sus vistas, y eso se hace con esas properties:

edgesForExtendedLayout

Básicamente, con esta propiedad se establece qué lados de su vista se pueden extender para cubrir toda la pantalla. Imagine que empuja un UIViewController a un UINavigationController . Cuando se visualice la vista del controller de vista, comenzará donde termina la barra de navigation, pero esta propiedad establecerá qué lados de la vista (superior, izquierda, inferior, derecha) pueden ampliarse para llenar toda la pantalla.

Déjalo ver con un ejemplo:

 UIViewController *viewController = [[UIViewController alloc] init]; viewController.view.backgroundColor = [UIColor networkingColor]; UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 

Aquí no está configurando el valor de edgesForExtendedLayout , por lo tanto, se toma el valor pnetworkingeterminado ( UIRectEdgeAll ), por lo que la vista amplía su layout para llenar toda la pantalla.

Este es el resultado:

sin bordes para diseño extendido, la vista llena toda la pantalla

Como puede ver, el background rojo se extiende detrás de la barra de navigation y la barra de estado.

Ahora, va a establecer ese valor en UIRectEdgeNone , por lo que le está diciendo al controller de vista que no extienda la vista para cubrir la pantalla:

 UIViewController *viewController = [[UIViewController alloc] init]; viewController.view.backgroundColor = [UIColor networkingColor]; viewController.edgesForExtendedLayout = UIRectEdgeNone; UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 

Y el resultado:

con el conjunto edgesForExtendedLayout, la vista está justo debajo de la navegación

Ajusta automáticamente las inputs de ScrollView.

Esta propiedad se utiliza cuando su vista es un UIScrollView o similar, como un UITableView . Desea que su tabla comience donde termina la barra de navigation, ya que no verá todo el contenido si no es así, pero al mismo time desea que su tabla cubra toda la pantalla al desplazarse. En ese caso, la configuration de edgesForExtendedLayout a None no funcionará porque su tabla comenzará a desplazarse hacia donde termina la barra de navigation y no irá detrás de ella.

Aquí es donde esta propiedad es útil, si deja que el controller de vista ajuste automáticamente las inserciones (configurando esta propiedad en SÍ, también el valor pnetworkingeterminado) agregará inserciones en la parte superior de la tabla, de modo que la tabla comenzará donde la navigation La barra termina, pero el desplazamiento cubrirá toda la pantalla.

Esto es cuando se establece en NO:

la tabla se desplazará por toda la pantalla, pero comienza parcialmente cubierta

Y SÍ (de forma pnetworkingeterminada):

la tabla se desplaza por toda la pantalla y comienza justo debajo de la navegación

En ambos casos, la tabla se desplaza detrás de la barra de navigation, pero en el segundo caso (SÍ), comenzará desde debajo de la barra de navigation.

extendedLayoutIncludesOpaqueBars

Este valor es solo una adición a los anteriores. De forma pnetworkingeterminada, este parámetro se establece en NO. Si la barra de estado es opaca, las vistas no se ampliarán para include la barra de estado, incluso si extiende su vista para cubrirla ( edgesForExtendedLayout to UIRectEdgeAll ).

Si configura el valor en SÍ, esto permitirá que la vista pase por debajo de la barra de estado otra vez.

Si algo no está claro, escriba un comentario y lo responderé.

¿Cómo sabe iOS qué es lo que usa UIScrollView?

iOS toma la primera subvista en la vista de ViewController, la que está en el índice 0, y si es una subclass de UIScrollView entonces aplica las properties explicadas.

Por supuesto, esto significa que UITableViewController funciona de manera pnetworkingeterminada (ya que UITableView es la primera vista).

No está seguro de si está utilizando storyboards, pero si lo está, para que los controlleres de vista comiencen debajo de la barra de estado (y encima de la barra inferior):

Seleccione el controller de vista en IB. En el inspector de attributes, anule la selección de "Extender bordes – Debajo de barras superiores" y "Extender bordes – Debajo barras inferiores".

Estoy usando storyboards y usando el consejo anterior funcionó, pero no estaba exactamente seguro de cómo implementarlo. A continuación se muestra un breve ejemplo de cómo solucionó el problema colocando la solución recomendada en ViewController.

 import Foundation import UIKit // This ViewController is connected to a view on a storyboard that // has a scrolling sub view. class TheViewController: UIViewController { // Prepares the view prior to loading. Putting it in viewDidAppear didn't work. override func viewWillAppear(animated: Bool) { // this method is an extension of the UIViewController // so using self works as you might expect. self.automaticallyAdjustsScrollViewInsets = false // Default is "true" so this sets it to false tells it to use // the storyboard as you have it placed // and not how it thinks it should place it. } } 

My Problem: Auto Adjust se establece en true de manera pnetworkingeterminada causando una diferencia entre el layout y el simulador de storyboard Ajuste automático configurado como verdadero de manera predeterminada que causa una diferencia entre el diseño y el simulador del guión gráfico.

Resuelto: se aplicó el código anterior, desactivando el ajuste automático. Se aplicó el código anterior, desactivando el ajuste automático.

Solucioné este problema agregando esta línea, pero mi problema estaba relacionado con una UIView , no con UIScrollView

 self.navigationController.navigationBar.translucent = NO; 

Solo tenga en count que automaticallyAdjustsScrollViewInsets propiedad automaticallyAdjustsScrollViewInsets solo funciona si algún tipo de vista de desplazamiento (vista de tabla, vista de colección, …) es

  • La vista de VC, o
  • Primera subvista de esta vista

Otros sugirieron que hace el trabajo incluso si es la primera subvista, pero hay otras vistas de desplazamiento en la jerarquía de la vista.

EDITAR (extensión DIY)

Si desea un comportamiento similar incluso si no puede cumplir estas condiciones (por ejemplo, tiene una image de background debajo de la vista de desplazamiento), puede ajustar manualmente las inserciones de la vista de desplazamiento. Pero no lo establezcas en constante como 44 o 64 o incluso 20 como muchos sugieren alnetworkingedor de SO. No puedes saber el tamaño de la historia. Puede haber la notificación incall / gps / audio, la barra de navigation no tiene que ser siempre 44 puntos, etc.

Creo que la mejor solución es utilizar la length de layoutGuide en didLayoutSubviews:

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0) scrollView.scrollIndicatorInsets = scrollView.contentInset } 

Puede usar el bottomLayoutGuide de la misma manera.