Restricciones de diseño mediante programación en Xamarin.iOS

En esta guía se presenta cómo trabajar con restricciones de diseño automático de iOS en código de C# en lugar de crearlas en iOS Designer.

El diseño automático (también denominado "diseño adaptable") es un enfoque de diseño dinámico. A diferencia del sistema de diseño transitorio, en el que la ubicación de cada elemento está codificada de forma segura hasta un punto de la pantalla, el diseño automático trata sobre las relaciones: las posiciones de los elementos con respecto a otros elementos en la superficie de diseño. En el núcleo del diseño automático se encuentra la idea de restricciones o reglas que definen la colocación de un elemento o conjunto de elementos en el contexto de otros elementos en la pantalla. Dado que los elementos no están asociados a una posición determinada en la pantalla, las restricciones ayudan a crear un diseño adaptable que se vea bien en diferentes tamaños de pantalla y orientaciones de dispositivo.

Normalmente, cuando se trabaja con diseño automático en iOS, se usa el Interface Builder Xcode para colocar gráficamente restricciones de diseño en los elementos de la interfaz de usuario. Sin embargo, puede haber ocasiones en las que necesite crear y aplicar restricciones en el código de C#. Por ejemplo, cuando se usan elementos de interfaz de usuario creados dinámicamente agregados a UIView .

En esta guía se muestra cómo crear y trabajar con restricciones mediante código de C# en lugar de crearlas gráficamente en el código de Xcode Interface Builder.

Crear restricciones mediante programación

Como se indicó anteriormente, normalmente trabajará con restricciones de diseño automático en el Diseñador de iOS. En aquellos casos en los que tenga que crear las restricciones mediante programación, tiene tres opciones entre las que elegir:

En las secciones siguientes se rebará cada opción en detalle.

Delimitadores de diseño

Mediante el uso de la clase , tiene una interfaz fluida para crear restricciones basadas en las propiedades delimitadoras de los elementos de interfaz de usuario NSLayoutAnchor que se restringen. Por ejemplo, las guías de diseño superior e inferior de un controlador de vistas exponen las propiedades de delimitador y , mientras que una vista expone las propiedades de borde, centro, tamaño y TopAnchorBottomAnchor línea de HeightAnchor base.

Importante

Además del conjunto estándar de propiedades de delimitador, las vistas de iOS también incluyen las LayoutMarginsGuides propiedades ReadableContentGuide y . Estas propiedades exponen objetos para trabajar con los márgenes de la vista y UILayoutGuide las guías de contenido legible respectivamente.

Los delimitadores de diseño proporcionan varios métodos para crear restricciones en un formato compacto y fácil de leer:

  • ConstraintEqualTo: define una relación donde con un valor de desplazamiento proporcionado constant opcionalmente.
  • ConstraintGreaterThanOrEqualTo: define una relación donde con un valor de desplazamiento proporcionado constant opcionalmente.
  • ConstraintLessThanOrEqualTo: define una relación donde con un valor de desplazamiento proporcionado constant opcionalmente.

Por ejemplo:

// Get the parent view's layout
var margins = View.LayoutMarginsGuide;

// Pin the leading edge of the view to the margin
OrangeView.LeadingAnchor.ConstraintEqualTo (margins.LeadingAnchor).Active = true;

// Pin the trailing edge of the view to the margin
OrangeView.TrailingAnchor.ConstraintEqualTo (margins.TrailingAnchor).Active = true;

// Give the view a 1:2 aspect ratio
OrangeView.HeightAnchor.ConstraintEqualTo (OrangeView.WidthAnchor, 2.0f);

Una restricción de diseño típica se puede expresar simplemente como una expresión lineal. Tome el ejemplo siguiente:

Una restricción de diseño expresada como una expresión lineal

Que se convertiría en la siguiente línea de código de C# mediante delimitadores de diseño:

PurpleView.LeadingAnchor.ConstraintEqualTo (OrangeView.TrailingAnchor, 10).Active = true; 

Donde las partes del código de C# corresponden a las partes dadas de la ecuación de la siguiente manera:

Ecuación Código
Elemento 1 PurpleView
Atributo 1 LeadingAnchor
Relación ConstraintEqualTo
Multiplicador El valor predeterminado es 1.0, por lo que no se especifica
Item 2 OrangeView
Atributo 2 TrailingAnchor
Constante 10.0

Además de proporcionar solo los parámetros necesarios para resolver una ecuación de restricción de diseño determinada, cada uno de los métodos de delimitador de diseño aplica la seguridad de tipos de los parámetros que se les pasan. Por lo tanto, los delimitadores de restricción horizontal, como o , solo se pueden usar con otros tipos de delimitadores horizontales y multiplicadores solo se LeadingAnchorTrailingAnchor proporcionan a las restricciones de tamaño.

Restricciones de diseño

Puede agregar restricciones de diseño automático manualmente mediante la construcción directa de un en NSLayoutConstraint código de C#. A diferencia del uso de delimitadores de diseño, debe especificar un valor para cada parámetro, incluso si no tendrá ningún efecto en la restricción que se está definindo. Como resultado, terminará generando una cantidad considerable de código reutilizable y difícil de leer. Por ejemplo:

//// Pin the leading edge of the view to the margin
NSLayoutConstraint.Create (OrangeView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, View, NSLayoutAttribute.LeadingMargin, 1.0f, 0.0f).Active = true;

//// Pin the trailing edge of the view to the margin
NSLayoutConstraint.Create (OrangeView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, View, NSLayoutAttribute.TrailingMargin, 1.0f, 0.0f).Active = true;

//// Give the view a 1:2 aspect ratio
NSLayoutConstraint.Create (OrangeView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, OrangeView, NSLayoutAttribute.Width, 2.0f, 0.0f).Active = true;

Donde la enumeración define el valor de los márgenes de la vista y se corresponde con las propiedades como , y y la enumeración define la relación que se creará entre los atributos especificados como , o NSLayoutAttributeLayoutMarginsGuideLeftRightTopBottomNSLayoutRelationEqualLessThanOrEqualGreaterThanOrEqual .

A diferencia de layout anchor API, los métodos de creación no resaltan los aspectos importantes de una restricción determinada y no se realizan comprobaciones de tiempo de NSLayoutConstraint compilación en la restricción. Como resultado, es fácil construir una restricción no válida que producirá una excepción en tiempo de ejecución.

Lenguaje de formato visual

El lenguaje de formato visual permite definir restricciones mediante el uso de elementos gráficos ASCII como cadenas que proporcionan una representación visual de la restricción que se va a crear. Esto tiene las siguientes ventajas y desventajas:

  • El lenguaje de formato visual solo aplica la creación de restricciones válidas.
  • Diseño automático genera restricciones en la consola mediante el lenguaje de formato visual para que los mensajes de depuración se parezcan al código usado para crear la restricción.
  • El lenguaje de formato visual permite crear varias restricciones al mismo tiempo con una expresión muy compacta.
  • Puesto que no hay ninguna validación del lado de compilación de las cadenas del lenguaje de formato visual, los problemas solo se pueden detectar en tiempo de ejecución.
  • Dado que el lenguaje de formato visual resalta la visualización sobre la integridad, algunos tipos de restricciones no se pueden crear con él (por ejemplo, las relaciones).

Al usar el lenguaje de formato visual para crear una restricción, siga estos pasos:

  1. Cree un objeto que contenga los objetos View y Las guías de diseño y una clave de cadena que NSDictionary se usará al definir los formatos.
  2. Opcionalmente, cree un NSDictionary que defina un conjunto de claves y valores ( ) NSNumber usados como el valor Constante para la restricción.
  3. Cree la cadena de formato para crear una sola columna o fila de elementos.
  4. Llame al FromVisualFormat método de la clase para generar las NSLayoutConstraint restricciones.
  5. Llame al ActivateConstraints método de la clase para activar y aplicar las NSLayoutConstraint restricciones.

Por ejemplo, para crear una restricción inicial y una restricción final en el lenguaje de formato visual, puede usar lo siguiente:

// Get views being constrained
var views = new NSMutableDictionary (); 
views.Add (new NSString ("orangeView"), OrangeView);

// Define format and assemble constraints
var format = "|-[orangeView]-|";
var constraints = NSLayoutConstraint.FromVisualFormat (format, NSLayoutFormatOptions.AlignAllTop, null, views);

// Apply constraints
NSLayoutConstraint.ActivateConstraints (constraints);

Dado que el lenguaje de formato visual siempre crea restricciones de punto cero asociadas a los márgenes de la vista primaria cuando se usa el espaciado predeterminado, este código genera resultados idénticos a los ejemplos presentados anteriormente.

Para diseños de interfaz de usuario más complejos, como varias vistas secundarias en una sola línea, el lenguaje de formato visual especifica tanto el espaciado horizontal como la alineación vertical. Como en el ejemplo anterior, donde especifica , alinea todas las vistas de una fila o AlignAllTopNSLayoutFormatOptions columna con sus elementos superiores.

Consulte el Apéndice del lenguaje de formato visual de Apple para ver algunos ejemplos de especificación de restricciones comunes y la gramática de cadenas de formato visual.

Resumen

En esta guía se presenta la creación y el trabajo con restricciones de diseño automático en C# en lugar de crearlas gráficamente en iOS Designer. En primer lugar, se ha visto el uso de delimitadores de diseño ( NSLayoutAnchor ) para controlar el diseño automático. A continuación, se mostró cómo trabajar con restricciones de diseño ( NSLayoutConstraint ). Por último, se presenta con el lenguaje de formato visual para el diseño automático.