ios layout view autolayout nslayoutanchor

En iOS, ¿cuáles son las diferencias entre márgenes, inserciones de borde, inserciones de contenido, rectas de alineación, márgenes de diseño, anclas...?



layout view (3)

Parece que hay varias opciones / términos y personas diferentes en el uso de la comunidad de iOS con respecto al diseño (por ejemplo, UIEdgeInsets es un tipo, pero a veces escucho / leo "establecer las inserciones" o márgenes de diseño frente a las guías de diseño).

Siempre he podido encontrar una opción que funcione. Pero nunca estoy seguro de estar usando la herramienta adecuada para el trabajo.

¿Puede alguien ayudar a proporcionar cierta claridad entre estos diferentes aspectos del diseño y cuándo usar cada uno de la mejor manera?



Lo siento si esta es una respuesta aburrida, pero creo que la documentación del desarrollador de Apple es bastante buena para describir cómo se utilizará cada propiedad UIView.

En cuanto a cuál es la mejor manera de implementar un diseño cuando tiene múltiples métodos / opciones que funcionan ... eso es realmente una cuestión de estilo / opinión. Me concentraría en los siguientes criterios para tomar una decisión:

  1. Considere eliminar las opciones más difíciles de mantener / depurar / comprender
    • Imagine que alguien nuevo se une a su equipo o alguien que hereda su código. ¿A qué implementación les resultaría difícil depurar y por qué?
  2. Considere eliminar las opciones que hacen que el diseño sea más difícil de reorganizar / expandir / editar
  3. Considere la posibilidad de eliminar las opciones que son inconsistentes con el resto de la aplicación (este tipo se remonta al primer punto)
  4. Considere la posibilidad de eliminar las opciones que van en contra de la intención de Apple (vea las conversaciones de docs / WWDC para tener una idea de sus intenciones).

Un equipo podría trabajar junto con este criterio para llegar a un acuerdo sobre "cómo diseñamos nuestra UI" en cada escenario. Supongo que lo que está pidiendo es el producto de la suma total de tales discusiones: una especie de guía de estilo para el diseño.

En mi experiencia, esto siempre se ha desarrollado orgánicamente en los equipos en los que he trabajado, y las cosas no estaban realmente escritas. Fue mucho más del siguiente punto 3 arriba.

Algunos extractos de la documentación de Apple para las clases que se describen en la pregunta:

En UILayoutGuide :

Use las guías de diseño para reemplazar las vistas ficticias que haya creado para representar espacios de visualización o encapsulación en su interfaz de usuario. Tradicionalmente, existían varias técnicas de diseño automático que requerían vistas ficticias.

...

La clase UILayoutGuide está diseñada para realizar todas las tareas previamente realizadas por vistas ficticias, pero para hacerlo de una manera más segura y eficiente.

En layoutMargins :

En iOS 11 y versiones posteriores, use la propiedad directionalLayoutMargins para especificar márgenes de diseño en lugar de esta propiedad.

En directionalLayoutMargins :

Use esta propiedad para especificar la cantidad deseada de espacio (medido en puntos) entre los bordes de esta vista y sus subvistas. Los márgenes iniciales y finales se aplican de manera adecuada a los márgenes izquierdo o derecho según la dirección de diseño actual.

En contentInset :

Utilice esta propiedad para ampliar el espacio entre su contenido y los bordes de la vista de contenido. La unidad de tamaño es puntos. El valor predeterminado es UIEdgeInsetsZero.

En topAnchor :

Utilice este anclaje para crear restricciones con el borde superior de la vista. Puede combinar este anclaje solo con otros anclajes NSLayoutYAxisAnchor. Para obtener más información, consulte NSLayoutAnchor.

En NSLayoutAnchor

Utilice estas restricciones para definir programáticamente su diseño utilizando Diseño automático. En lugar de crear objetos NSLayoutConstraint directamente, comience con un objeto UIView, NSView o UILayoutGuide que desee restringir, y seleccione una de las propiedades de anclaje de ese objeto. Estas propiedades corresponden a los valores principales de NSLayoutConstraint.Attribute utilizados en el diseño automático, y proporcionan una subclase NSLayoutAnchor apropiada para crear restricciones para ese atributo. Usa los métodos del ancla para construir tu restricción.


Siendo el oferente de Bounty ... Diría que la mayor parte de mi confusión provino de no entender correctamente la clase UILayoutGuide . Eso es clave, pero también muy simple.

Permítanme primero presentar un problem :

En los viejos tiempos, si necesitabas restringir estos círculos de esta manera:

Luego tuvo que crear UIViews claras y agregarlas como sus subvistas y luego agregar sus restricciones a ellas como a continuación:

Hoy no necesitas agregarlos como tus subvistas. Podrías en cambio solo

Creación de guías de diseño

Para crear una guía de diseño, debe realizar los siguientes pasos:

  1. Crea una nueva guía de diseño.
  2. Agregue la guía de diseño a una vista llamando al método addLayoutGuide(_:) .
  3. Defina la posición y el tamaño de la guía de diseño utilizando Diseño automático. Puede usar estas guías para definir el espacio entre los elementos de su diseño. El siguiente ejemplo muestra las guías de diseño utilizadas para definir un espaciado igual entre una serie de vistas.

pasos:

let space1 = UILayoutGuide() view.addLayoutGuide(space1) let space2 = UILayoutGuide() view.addLayoutGuide(space2) space1.widthAnchor.constraintEqualToAnchor(space2.widthAnchor).active = true saveButton.trailingAnchor.constraintEqualToAnchor(space1.leadingAnchor).active = true cancelButton.leadingAnchor.constraintEqualToAnchor(space1.trailingAnchor).active = true cancelButton.trailingAnchor.constraintEqualToAnchor(space2.leadingAnchor).active = true clearButton.leadingAnchor.constraintEqualToAnchor(space2.trailingAnchor).active = true

Las guías de diseño también pueden actuar como una caja negra, que contiene una cantidad de otras vistas y controles. Esto le permite encapsular parte de su vista, dividiendo su diseño en trozos modulares.

Tres notas interesantes:

  1. Si está utilizando la ''jerarquía de depuración de la vista'', vería más instancias de UILayoutGuide
  2. Al igual que un UIView, una instancia de UILayoutGuide tiene todo tipo de anclajes
  3. En cuanto a por qué no solo crear UIViews ficticias y crear UILayoutGuides: "Hay una serie de costos asociados con la adición de vistas ficticias a su jerarquía de vistas. Primero, existe el costo de crear y mantener la vista en sí. En segundo lugar, la vista ficticia es un miembro completo de la jerarquía de vistas, lo que significa que agrega sobrecarga a cada tarea que realiza la jerarquía. Lo peor de todo es que la vista ficticia invisible puede interceptar mensajes que están destinados a otras vistas, causando problemas que son muy difíciles de encontrar ".

Para más información ver UILayoutGuide .

topLayoutGuide vs. safeAreaLayoutGuide

topLayoutGuide (en desuso)

Está en desuso por motivos de aprendizaje: un UIViewController tiene 2 cajas de UIViewController . 1 propiedad en la parte superior llamada topLayoutGuide y otra propiedad en la parte inferior llamada bottomLayoutGuide . El viewController en sí mismo no tiene guías para sus lados izquierdo / delantero o derecho / trasero. Ambos son una instancia de UILayoutGuide

si está restringido a ver.topAnchor es decir:

tableView.topAnchor.constraint(equalTo: view.topAnchor)

tableView no comienza desde la parte inferior de la barra de navegación

si está restringido a topLayoutGuide.bottomAnchor es decir:

tableView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)

tableView comienza desde la parte inferior de la barra de navegación

Y dependiendo del diseño de su diseño, es posible que desee que el contenido aparezca borroso debajo de la barra de navegación.

Y la idea era que mostrarías tu contenido de borde a borde. Y se traslaparían las barras para que puedas obtener estos bonitos borrones de colores con tu contenido a través de las barras

Para más información, vea este momento de WWDC y esta pregunta here . No creo que las soluciones estén exactamente relacionadas, solo la imagen en la pregunta.

SafeAreaLayoutGuide

desde iOS11

Apple ha desaprobado topLayoutGuide y bottomLayoutGuide . Entonces, en lugar de tener 2 cajas ficticias, ahora tiene 1 caja ficticia llamada safeAreaLayoutGuide en la instancia de UIView. UIViewController ya no tiene nada de esto ... Una comparación visual copiada de useyourloaf :

Nota al margen: si usa guiones gráficos, la alineación de sus vistas con TopLayoutGuide o top of safeAreaLayoutGuide se mostraría igual. Si no utilizas guiones gráficos (hazlo mediante programación), deberías bailar entre iOS11 y LessThaniOS11 y tener 2 versiones diferentes de código.

Para obtener más información sobre safeAreaLayoutGuide , le recomiendo encarecidamente que configure el artículo de Apple sobre: ​​Posicionamiento del contenido en relación con el área segura

layoutMarginsGuide

  • UIView tiene solo 1 caja falsa. La propiedad se llama layoutMarginsGuide . Pero a diferencia de UIViewController , no se sienta en la parte superior o inferior. Simplemente se sienta en el centro con 8 puntos de relleno / inserción (de los 4 lados) en el UIView . Entonces, ¿dónde es esto útil? : Usaría esto si no quiere que su textView se limite a los bordes de una instancia de UIView. Esto mejoraría la experiencia de lectura. O en lugar de restringir un botón al borde anterior de su supervisión y hacer que se vea feo, agregue 8 puntos al ancla ... es decir, restrinja el botón al líder anterior y luego agregue 8 puntos constantes. El texto en huelga, en realidad es donde usaría layoutMarginsGuide , layoutMarginsGuide es útil si para cuando no quiere que su botón o etiqueta esté anclado al borde de su supervisión.

    someButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8)

    Pero espere hay una manera más fácil. Solo usa el margen recomendado de Apple, es decir, usa:

    someButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor)

    Vea también el ejemplo provisto en la documentation . Un buen tutorial de Raywenderlich se puede encontrar here

readableContentGuide

  • Es un poco diferente de layoutMarginGuide . Ambas son propiedades de UIView. A veces son idénticas, a veces no lo son. Su propósito es:

    Esta guía de diseño define un área que se puede leer fácilmente sin obligar a los usuarios a mover la cabeza para seguir las líneas

    Para más información, vea este momento de WWDC: construyendo un diseño adaptable y este tutorial increíble de useyourloaf .

    En el iPhone 7 Plus en formato vertical, las guías de contenido legibles son las mismas que las guías de margen de la vista, pero en el paisaje hay más espacio en blanco a cada lado de la vista de texto. En el iPad en paisaje, el espacio en blanco se incrementa significativamente.

    El tamaño del margen depende del tipo dinámico del sistema. Cuanto más grande sea la fuente, más ancha será la guía.

    De here

En la imagen de abajo, el cian está anclado en el layoutMarginGuide, pero el azul está anclado en el legibleContentGuide:

UIEdgeInsets

  • Si desea cambiar su layoutMarginsGuide es decir, cambiarlo de 8 puntos a 16 puntos, entonces debe cambiar el valor de layoutMarginsGuide y luego los layoutMarginsGuide de layoutMarginsGuide se actualizarán automáticamente. UIEdgeInsets es solo el tipo de sus layoutMargins . layoutMargins es un nombre de propiedad de la clase UIView

    someview.layoutMargins = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)

    El único lugar donde encontré este código ☝️ para que tenga efecto es dentro de viewDidLayoutSubviews Para más información, viewDidLayoutSubviews here

  • Los anclajes no son especiales. Son el borde más lejano de cualquier UIView / UILayoutGuide. Ambas instancias UIView y UIlayoutGuide lo tienen. TODO lo que restringe se restringe con el uso de los anclajes, es solo una cuestión de a qué anclajes de la entidad lo está anclando. Podría ser el ancla de safeAreaLayoutGuide , podría ser el ancla de safeAreaLayoutGuide , podría ser el ancla de layoutMarginGuide , podría ser el ancla de una view . (aunque también puede anclar su altura Ancla a 50, por lo que en ese caso no hay otro ancla)

    De esta answer se puede encontrar una gran comparación visual entre layoutMarginsGuide y Anchors . Se hace usando guiones gráficos para que sea más fácil de entender.

  • contentInsets realmente no tiene nada que ver con los demás. Para más información vea este artículo.

Conclusión

Para estar seguro y seguro de que todo está dentro de su vista, use safeAreaLayoutGuide . Si desea usar los márgenes provistos por el sistema para tener un mejor diseño de las vistas o tener algo de relleno, use layoutMarginGuide , si desea que las cosas sean más readableContentGuide .

El tamaño de layoutMarginGuide es siempre más pequeño o igual que layoutMarginGuide .
El tamaño de layoutMarginGuide es siempre más pequeño o igual que safeAreaLayoutGuide

layoutMargins es muy similar al relleno de CSS. safeAreaLayoutGuide es similar a los bordes de CSS. No sé si hay algún equivalente de CSS para readableContentGuide

ContentInset vs. contentOffset

Son para scrollViews, y no están relacionados con el resto de la respuesta. En lo que contentInset y contentOffset , vea este momento en WWDC 2018: UIKit: Aplicaciones para todos los tamaños y formas . El video es muy simple. Consulte también la respuesta de Karthik a continuación. Habiendo dicho eso, es vital que entiendas completamente cómo funciona un scrollView y que entiendas qué es contentSize , de lo contrario sería complicado. Para más información sobre contentSize y scrollView vea la respuesta de Vacawama aquí