Vistas de pila en Xamarin.iOS

En este artículo se describe el uso del nuevo control UIStackView en una aplicación de Xamarin.iOS para administrar un conjunto de subvistas en una pila organizada horizontal o verticalmente.

Importante

Tenga en cuenta que, aunque StackView es compatible con iOS Designer, puede encontrar errores de facilidad de uso al usar el canal estable. Cambiar los canales Beta o Alfa debe aliviar este problema. Hemos decidido presentar este tutorial mediante Xcode hasta que las correcciones necesarias se implementen en el canal estable.

El control Vista de pila (UIStackView) aprovecha la eficacia de las clases de diseño automático y tamaño para administrar una pila de subvistas, ya sea horizontal o verticalmente, que responde dinámicamente a la orientación y el tamaño de pantalla del dispositivo iOS.

El diseño de todas las subvistas adjuntas a una vista de pila se administra en función de las propiedades definidas por el desarrollador, como el eje, la distribución, la alineación y el espaciado:

Stack View layout diagram

Cuando se usa en UIStackView una aplicación de Xamarin.iOS, el desarrollador puede definir las subvistas dentro de un Guión gráfico en iOS Designer o agregando y quitando subvistas en código de C#.

Este documento consta de dos partes: un inicio rápido para ayudarle a implementar la primera vista de pila y, a continuación, algunos detalles más técnicos sobre cómo funciona.

Vídeo UIStackView

Inicio rápido de UIStackView

Como introducción rápida al UIStackView control, vamos a crear una interfaz sencilla que permita al usuario escribir una clasificación de 1 a 5. Usaremos dos vistas de pila: una para organizar la interfaz verticalmente en la pantalla del dispositivo y otra para organizar los iconos de clasificación de 1 a 5 horizontalmente a través de la pantalla.

Definición de la interfaz de usuario

Inicie un nuevo proyecto de Xamarin.iOS y edite el archivo Main.storyboard en el Generador de interfaces de Xcode. En primer lugar, arrastre una sola vista de pila vertical en el controlador de vista:

Drag a single Vertical Stack View on the View Controller

En el Inspector de atributos, establezca las siguientes opciones:

Set the Stack View options

Donde:

  • Eje : determina si la vista de pila organiza las subvistas horizontal overticalmente.
  • Alineación : controla cómo se alinean las subvistas dentro de la vista de pila.
  • Distribución : controla el tamaño de las subvistas dentro de la vista de pila.
  • Espaciado : controla el espacio mínimo entre cada subvista de la vista de pila.
  • Valor relativo de línea base: si está activado, el espaciado vertical de cada subvista se derivará de la línea base.
  • Márgenes de diseño relativos : coloca las subvistas en relación con los márgenes de diseño estándar.

Al trabajar con una vista de pila, puede considerar la alineación como la ubicación X e Y de la subvista y la distribución como alto y ancho.

Importante

UIStackView está diseñado como una vista de contenedor que no es de representación y, como tal, no se dibuja en el lienzo como otras subclases de UIView. Por lo tanto, establecer propiedades como BackgroundColor o invalidar DrawRect no tendrá ningún efecto visual.

Continúe con el diseño de la interfaz de la aplicación agregando una etiqueta, ImageView, dos botones y una vista de pila horizontal para que se parezca a lo siguiente:

Laying out the Stack View UI

Configure la vista De pila horizontal con las siguientes opciones:

Configure the Horizontal Stack View options

Dado que no queremos que el icono que represente cada "punto" de la clasificación se extienda cuando se agrega a la vista pila horizontal, hemos establecido la alineación en El centro y la distribución en Rellenar igualmente.

Por último, conecte las siguientes salidas y acciones:

The Stack View Outlets and Actions

Rellenar un UIStackView desde code

Vuelva a Visual Studio para Mac y edite el archivo ViewController.cs y agregue el código siguiente:

public int Rating { get; set;} = 0;
...

partial void IncreaseRating (Foundation.NSObject sender) {

    // Maximum of 5 "stars"
    if (++Rating > 5 ) {
        // Abort
        Rating = 5;
        return;
    }

    // Create new rating icon and add it to stack
    var icon = new UIImageView (new UIImage("icon.png"));
    icon.ContentMode = UIViewContentMode.ScaleAspectFit;
    RatingView.AddArrangedSubview(icon);

    // Animate stack
    UIView.Animate(0.25, ()=>{
        // Adjust stack view
        RatingView.LayoutIfNeeded();
    });

}

partial void DecreaseRating (Foundation.NSObject sender) {

    // Minimum of zero "stars"
    if (--Rating < 0) {
        // Abort
        Rating =0;
        return;
    }

    // Get the last subview added
    var icon = RatingView.ArrangedSubviews[RatingView.ArrangedSubviews.Length-1];

    // Remove from stack and screen
    RatingView.RemoveArrangedSubview(icon);
    icon.RemoveFromSuperview();

    // Animate stack
    UIView.Animate(0.25, ()=>{
        // Adjust stack view
        RatingView.LayoutIfNeeded();
    });
}

Echemos un vistazo a algunos fragmentos de este código con detalle. En primer lugar, usamos instrucciones if para comprobar que no hay más de cinco "estrellas" o menos de cero.

Para agregar una nueva "estrella", cargamos su imagen y establecemos su modo de contenido en Ajuste de aspecto de escala:

var icon = new UIImageView (new UIImage("icon.png"));
icon.ContentMode = UIViewContentMode.ScaleAspectFit;

Esto impide que el icono de "estrella" se distorsiona cuando se agrega a la vista de pila.

A continuación, agregamos el nuevo icono de "estrella" a la colección de subvistas de la vista de pila:

RatingView.AddArrangedSubview(icon);

Observará que hemos agregado el UIImageView elemento a la UIStackViewpropiedad de ArrangedSubviews y no a SubView. Cualquier vista que desee que la vista de pila controle su diseño debe agregarse a la ArrangedSubviews propiedad .

Para quitar una subvista de una vista de pila, primero obtenemos la subvista para quitar:

var icon = RatingView.ArrangedSubviews[RatingView.ArrangedSubviews.Length-1];

A continuación, es necesario quitarlo de la ArrangedSubviews colección y de la Vista super:

// Remove from stack and screen
RatingView.RemoveArrangedSubview(icon);
icon.RemoveFromSuperview();

Quitar una subvista de solo la ArrangedSubviews colección lo saca del control de la vista de pila, pero no lo quita de la pantalla.

Prueba de la interfaz de usuario

Con todos los elementos y código de la interfaz de usuario necesarios, ahora puede ejecutar y probar la interfaz. Cuando se muestra la interfaz de usuario, todos los elementos de la vista Pila vertical se espaciarán de arriba a abajo.

Cuando el usuario pulsa el botón Aumentar clasificación , se agrega otra "estrella" a la pantalla (hasta un máximo de 5):

The sample app run

Las "estrellas" se centrarán automáticamente y se distribuirán igualmente en la vista pila horizontal. Cuando el usuario pulsa el botón Disminuir clasificación, se quita una "estrella" (hasta que no quede ninguna).

Detalles de la vista de pila

Ahora que tenemos una idea general de lo que es el UIStackView control y cómo funciona, echemos un vistazo más profundo a algunas de sus características y detalles.

Clases de tamaño y diseño automático

Como vimos anteriormente, cuando se agrega una subvista a una vista de pila su diseño está totalmente controlado por esa vista de pila mediante clases de diseño automático y tamaño para colocar y ajustar el tamaño de las vistas organizadas.

La vista de pila anclará la primera y la última subvista de su colección a los bordes superior e inferior para las vistas de pila vertical o los bordes izquierdo y derecho para las vistas de pila horizontal. Si establece la LayoutMarginsRelativeArrangement propiedad trueen , la vista ancla las subvistas a los márgenes pertinentes en lugar del borde.

La vista de pila usa la propiedad de IntrinsicContentSize la subvista al calcular el tamaño de las subvistas a lo largo del definido Axis (excepto para ).FillEqually Distribution FillEqually Distribution Cambia el tamaño de todas las subvistas para que tengan el mismo tamaño, rellenando así la vista pila a lo largo de .Axis

Con la excepción de Fill Alignment, la vista de pila usa la propiedad de IntrinsicContentSize la subvista para calcular el tamaño de la vista perpendicular al especificado Axis. Fill AlignmentPara , todas las subvistas tienen un tamaño para que rellenen la vista de pila perpendicular a la especificadaAxis.

Posicionamiento y ajuste del tamaño de la vista de pila

Aunque la vista de pila tiene control total sobre el diseño de cualquier subvista (en función de propiedades como Axis y Distribution), todavía tiene que colocar la vista pila (UIStackView) dentro de su vista primaria mediante el diseño automático y las clases de tamaño.

Por lo general, esto significa anclar al menos dos bordes de la vista de pila para expandir y contraer, definiendo así su posición. Sin restricciones adicionales, la vista de pila se cambiará automáticamente para ajustarse a todas sus subvistas de la siguiente manera:

  • El tamaño a lo largo de su Axis será la suma de todos los tamaños de subvista más cualquier espacio que se haya definido entre cada subvista.
  • Si la LayoutMarginsRelativeArrangement propiedad es true, el tamaño de las vistas de pila también incluirá espacio para los márgenes.
  • El tamaño perpendicular al Axis se establecerá en la subvista más grande de la colección.

Además, puede especificar restricciones para el alto y el ancho de la vista de pila. En este caso, las subvistas se colocarán (tamaño) para rellenar el espacio especificado por la vista de pila según lo determinen las Distribution propiedades y Alignment .

Si la BaselineRelativeArrangement propiedad es true, las subvistas se colocarán en función de la línea base de la primera o última subvista, en lugar de usar la posición Superior, Inferior o Central- Y. Estos se calculan en el contenido de la vista de pila de la siguiente manera:

  • Una vista de pila vertical devolverá la primera subvista de la primera línea base y la última para la última. Si cualquiera de estas subvistas son vistas de pila, se usará su primera o última línea de base.
  • Una vista de pila horizontal usará su subvista más alta para la primera y la última línea base. Si la vista más alta también es una vista de pila, usará su subvista más alta como línea base.

Importante

La alineación de línea base no funciona en tamaños de subvista extendidos o comprimidos, ya que la línea base se calculará en la posición incorrecta. En Alineación de línea base, asegúrese de que el alto de la subvista coincide con el alto de la vista de contenido intrínseco.

Usos comunes de la vista de pila

Hay varios tipos de diseño que funcionan bien con los controles Vista de pila. Según Apple, estos son algunos de los usos más comunes:

  • Defina el tamaño a lo largo del eje : al anclar ambos bordes a lo largo de Axis la vista de pila y uno de los bordes adyacentes para establecer la posición, la vista Pila crecerá a lo largo del eje para ajustarse al espacio definido por sus subvistas.
  • Definir la posición de la subvista: al anclar a los bordes adyacentes de la vista de pila a la vista primaria, la vista pila crecerá en ambas dimensiones para ajustarse a las subvistas que contiene.
  • Definir el tamaño y la posición de la pila : al anclar los cuatro bordes de la vista de pila a la vista primaria, la vista pila organiza las subvistas en función del espacio definido en la vista de pila.
  • Definir el tamaño perpendicular al eje : al anclar ambos bordes perpendiculares al de la vista de Axis pila y uno de los bordes del eje para establecer la posición, la vista Pila crecerá perpendicular al eje para ajustarse al espacio definido por sus subvistas.

Administrar la apariencia

UIStackView está diseñado como una vista de contenedor que no es de representación y, como tal, no se dibuja en el lienzo como en otras subclases de UIView. Establecer propiedades como BackgroundColor o invalidar DrawRect no tendrá ningún efecto visual.

Hay varias propiedades que controlan cómo una vista de pila organizará su colección de subvistas:

  • Eje : determina si la vista de pila organiza las subvistas horizontal overticalmente.
  • Alineación : controla cómo se alinean las subvistas dentro de la vista de pila.
  • Distribución : controla el tamaño de las subvistas dentro de la vista de pila.
  • Espaciado : controla el espacio mínimo entre cada subvista de la vista de pila.
  • Valor relativo de línea base: si truees , el espaciado vertical de cada subvista se derivará de su línea base.
  • Márgenes de diseño relativos : coloca las subvistas en relación con los márgenes de diseño estándar.

Normalmente, usará una vista de pila para organizar un pequeño número de subvistas. Las interfaces de usuario más complejas se pueden crear anidando una o varias vistas de pila entre sí (como hicimos en la guía de inicio rápido UIStackView anterior).

Puede ajustar aún más la apariencia de las interfaces de usuario agregando restricciones adicionales a las subvistas (por ejemplo, para controlar el alto o el ancho). Sin embargo, se debe tener cuidado de no incluir restricciones conflictivas a las introducidas por la propia vista de pila.

Mantenimiento de las vistas organizadas y la coherencia de las sub vistas

La vista de pila garantizará que su ArrangedSubviews propiedad siempre sea un subconjunto de su Subviews propiedad mediante las siguientes reglas:

  • Si se agrega una subvista a la ArrangedSubviews colección, se agregará automáticamente a la Subviews colección (a menos que ya forme parte de esa colección).
  • Si se quita una subvista de la Subviews colección (se quita de la pantalla), también se quita de la ArrangedSubviews colección.
  • Quitar una subvista de la ArrangedSubviews colección no la quita de la Subviews colección. Por lo tanto, ya no estará disponible en la vista de pila, pero seguirá siendo visible en la pantalla.

La ArrangedSubviews colección siempre es un subconjunto de la Subview colección, pero el orden de las subvistas individuales dentro de cada colección es independiente y controlado por lo siguiente:

  • El orden de las subvistas dentro de la ArrangedSubviews colección determina su orden de presentación dentro de la pila.
  • El orden de las subvistas dentro de la Subview colección determina su orden Z (o capas) dentro de la vista hacia delante.

Cambio dinámico del contenido

Una vista de pila ajustará automáticamente el diseño de las subvistas cada vez que se agrega, quita o oculta una subvista. El diseño también se ajustará si se ajusta cualquier propiedad de la vista de pila (por ejemplo, su Axis).

Los cambios de diseño se pueden animar colocando dentro de un bloque de animación, por ejemplo:

// Animate stack
UIView.Animate(0.25, ()=>{
    // Adjust stack view
    RatingView.LayoutIfNeeded();
});

Muchas de las propiedades de la vista de pila se pueden especificar mediante clases de tamaño dentro de un guión gráfico. Estas propiedades se animarán automáticamente es la respuesta a los cambios de tamaño o orientación.

Resumen

En este artículo se ha tratado el nuevo UIStackView control (para iOS 9) para administrar un conjunto de subvistas en una pila organizada horizontal o verticalmente en una aplicación de Xamarin.iOS. Comenzó con un ejemplo sencillo de uso de vistas de pila para crear una interfaz de usuario y terminó con un vistazo más detallado a las vistas de pila y sus propiedades y características.