Compartir vía


Introducción a MonoTouch.Dialog para Xamarin.iOS

MonoTouch.Dialog, denominado MT.D para abreviar, es un kit de herramientas de desarrollo rápido de la interfaz de usuario que permite a los desarrolladores crear pantallas de aplicaciones y navegación con información, en lugar del de tener que crear controladores de vista, tablas, etc. Por lo tanto, simplifica mucho el desarrollo de la interfaz de usuario y reduce el código. Por ejemplo, observe el siguiente escenario:

Por ejemplo, considere esta captura de pantalla.

Se usó el código siguiente para definir toda esta pantalla:

public enum Category
{
    Travel,
    Lodging,
    Books
}
        
public class Expense
{
    [Section("Expense Entry")]

    [Entry("Enter expense name")]
    public string Name;
    [Section("Expense Details")]
  
    [Caption("Description")]
    [Entry]
    public string Details;
        
    [Checkbox]
    public bool IsApproved = true;
    [Caption("Category")]
    public Category ExpenseCategory;
}

Al trabajar con tablas en iOS, a menudo se repite una gran cantidad de código. Por ejemplo, cada vez que se necesita una tabla, se necesita un origen de datos para rellenar esa tabla. En una aplicación que tiene dos pantallas basadas en tablas que están conectadas a través de un controlador de navegación, cada pantalla comparte gran parte del mismo código.

MT.D lo simplifica encapsulando todo ese código en una API genérica para la creación de tablas. A continuación, proporciona una abstracción sobre esa API que permite una sintaxis declarativa de enlace de objetos que lo facilita aún más. Por lo tanto, hay dos API disponibles en MT.D:

  • Elements API de bajo nivel: la Elements API se basa en la creación de un árbol jerárquico de elementos que representan pantallas y sus componentes. Elements API proporciona a los desarrolladores la mayor flexibilidad y control a la hora de crear las interfaces de usuario. Además, Elements API cuenta con compatibilidad avanzada para la definición declarativa a través de JSON, lo que permite una declaración increíblemente rápida, así como la generación dinámica de la interfaz de usuario desde un servidor.
  • API de reflexión de alto nivel: también conocida como la API deenlace , en la que las clases se anotan con sugerencias de interfaz de usuario y, a continuación, MT. D crea automáticamente pantallas basadas en los objetos y proporciona un enlace entre lo que se muestra (y, opcionalmente, se edita) en pantalla y la copia de seguridad del objeto subyacente. En el ejemplo anterior se ilustra el uso de Reflection API. Esta API no proporciona el control preciso que sí proporciona la API de elementos, pero reduce aún más la complejidad mediante la creación automática de la jerarquía de elementos basada en atributos de clase.

MT.D viene con un gran conjunto de elementos de interfaz de usuario integrados para la creación de pantallas, pero también reconoce la necesidad de elementos personalizados y diseños de pantalla avanzados. Por lo tanto, la extensibilidad es una característica de primera clase que se integra en la API. Los desarrolladores pueden ampliar los elementos existentes o crear otros nuevos y, a continuación, integrarlos sin problemas.

Además, MT.D tiene una serie de características comunes de la experiencia de usuario de iOS integradas, como la compatibilidad con "deslizamiento hacia abajo para actualizar", la carga asincrónica de imágenes y la compatibilidad con búsquedas.

En este artículo se analizará de forma completa el modo de trabajar con tablas, entre las que se incluyen:

  • Componentes de MT.D: se centrará en comprender las clases que componen MT.D para permitir que se ponga al día rápidamente.
  • Referencia de elementos: una lista completa de los elementos integrados de MT.D.
  • Uso avanzado: trata características avanzadas, como el deslizamiento hacia abajo para actualizar, la búsqueda, la carga de imágenes de fondo, el uso de LINQ para crear jerarquías de elementos y crear elementos, celdas y controladores personalizados para su uso con MT.D.

Configuración de MT.D

MT.D se distribuye con Xamarin.iOS. Para usarlo, haga clic con el botón derecho en el nodo Referencias de un proyecto de Xamarin.iOS en Visual Studio 2017 o Visual Studio para Mac y agregue una referencia al ensamblado MonoTouch.Dialog-1. A continuación, agregue using MonoTouch.Dialog instrucciones en el código fuente según sea necesario.

Descripción de los fragmentos de MT.D

Incluso cuando se usa Reflection API, MT. D crea una jerarquía de elementos en el centro, como si se hubiera creado directamente a través de Elements API. Además, la compatibilidad con JSON mencionada en la sección anterior también crea elementos. Por esta razón, es importante tener una comprensión básica de las partes que constituyen MT.D.

MT. D compila pantallas con las cuatro partes siguientes:

  • DialogViewController
  • RootElement
  • Sección
  • Element

DialogViewController

Un DialogViewController, o DVC para abreviar, hereda de UITableViewController y, por tanto, representa una pantalla con una tabla. Los DVC se pueden insertar en un controlador de navegación igual que un UITableViewController normal.

RootElement

Un RootElement es el contenedor de nivel superior de los elementos que entran en un DVC. Contiene secciones, que pueden contener elementos. RootElements no se representa; en su lugar, son simplemente contenedores para lo que realmente se representa. Un elemento RootElement se asigna a un DVC y, a continuación, el DVC representa sus elementos secundarios.

Sección

Una sección es un grupo de celdas de una tabla. Al igual que con una sección de tabla normal, opcionalmente puede tener un encabezado y un pie de página que pueden ser texto o incluso vistas personalizadas, como en la captura de pantalla siguiente:

Al igual que con una sección de tabla normal, puede tener opcionalmente un encabezado y pie de página que puede ser texto o incluso vistas personalizadas, como en esta captura de pantalla

Elemento

Un elemento representa una celda real de la tabla. MT.D viene con una amplia variedad de elementos que representan diferentes tipos de datos o distintas entradas. Por ejemplo, las capturas de pantalla siguientes muestran algunos de los elementos disponibles:

Por ejemplo, estas capturas de pantalla muestran algunos de los elementos disponibles.

Más información sobre secciones y RootElements

Ahora se analizarán RootElements y secciones con más detalle.

RootElements

Se necesita al menos un elemento RootElement para iniciar el proceso MonoTouch.Dialog.

Si se inicializa RootElement con un valor de sección o elemento, este valor se usa para buscar un elemento secundario que proporcionará un resumen de la configuración, que se representa en el lado derecho de la pantalla. Por ejemplo, en la captura de pantalla siguiente se muestra una tabla a la izquierda con una celda que contiene el título de la pantalla de detalles de la derecha, "Postre", junto con el valor del postre seleccionado.

En esta captura de pantalla se muestra una tabla a la izquierda con una celda que contiene el título de la pantalla de detalles a la derecha, Postre, junto con el valor del desierto seleccionado.En esta captura de pantalla siguiente se muestra una tabla a la izquierda con una celda que contiene el título de la pantalla de detalles a la derecha, Postre, junto con el valor del desierto seleccionado.

Los elementos raíz también se pueden usar dentro de Secciones para desencadenar la carga de una nueva página de configuración anidada, como se mostró anteriormente. Cuando se usa en este modo, el título proporcionado se usa mientras se representa dentro de una sección y también se usa como título de la subpágina. Por ejemplo:

var root = new RootElement ("Meals") {
    new Section ("Dinner") {
        new RootElement ("Dessert", new RadioGroup ("dessert", 2)) {
            new Section () {
                new RadioElement ("Ice Cream", "dessert"),
                new RadioElement ("Milkshake", "dessert"),
                new RadioElement ("Chocolate Cake", "dessert")
            }
        }
    }
};

En el ejemplo anterior, cuando el usuario pulsa "Postre", MonoTouch.Dialog creará una nueva página, navegará a ella con la raíz "Postre" y tendrá un grupo de radio con tres valores.

En este ejemplo concreto, el grupo de radio seleccionará "Pastel de chocolate" en la sección "Postre" porque hemos pasado el valor "2" a RadioGroup. Esto significa elegir el tercer elemento de la lista (índice cero).

Llamar al método Agregar o usar la sintaxis del inicializador de C# 4 agrega secciones. Los métodos Insertar se proporcionan para insertar secciones con una animación.

Si crea el RootElement con una instancia de Group (en lugar de un elemento RadioGroup), el valor de resumen del RootElement cuando se muestra en una sección será el recuento acumulativo de todos los BooleanElements y CheckboxElements que tienen la misma clave que el valor de Group.Key.

Secciones

Las secciones se usan para agrupar elementos en la pantalla y son los únicos elementos secundarios directos válidos del RootElement. Las secciones pueden contener cualquiera de los elementos estándar, incluidos los nuevos elementos RootElement.

Los elementos RootElement insertados en una sección se usan para navegar a un nuevo nivel más profundo.

Las secciones pueden tener encabezados y pies de página como cadenas o como UIViews. Normalmente solo usará las cadenas, pero para crear interfaces de usuario personalizadas, puede usar cualquier UIView como encabezado o pie de página. Puede usar una cadena para crearlas de la siguiente forma:

var section = new Section ("Header", "Footer");

Para usar vistas, simplemente pase las vistas al constructor:

var header = new UIImageView (Image.FromFile ("sample.png"));
var section = new Section (header);

Recibir notificaciones

Control de NSAction

MT.D muestra un NSAction como delegado para controlar las devoluciones de llamada. Por ejemplo, digamos que desea controlar un evento táctil de una celda de tabla creada por MT.D. Al crear un elemento con MT.D, simplemente proporciona una función de devolución de llamada, como se muestra a continuación:

new Section () {
    new StringElement ("Demo Callback", delegate { Console.WriteLine ("Handled"); })
}

Recuperación del valor del elemento

En combinación con la propiedad Element.Value, la devolución de llamada puede recuperar el valor establecido en otros elementos. Por ejemplo, suponga el siguiente código:

var element = new EntryElement (task.Name, "Enter task description", task.Description);
                
var taskElement = new RootElement (task.Name) {
    new Section () { element },
    new Section () { new DateElement ("Due Date", task.DueDate) },
    new Section ("Demo Retrieving Element Value") {
        new StringElement ("Output Task Description", delegate { Console.WriteLine (element.Value); })
    }
};

Este código crea una interfaz de usuario como se muestra a continuación. Para ver un tutorial completo de este ejemplo, consulte el tutorial de la API Elements.

Combinado con la propiedad Element.Value, la devolución de llamada puede recuperar el valor establecido en otros elementos.

Cuando el usuario presiona la celda de la tabla inferior, se ejecuta el código de la función anónima, escribiendo el valor de la instancia de element panel Salida de la aplicación en Visual Studio para Mac.

Elementos integrados

MT.D incluye una serie de elementos de celda de tabla integrados conocidos como elementos. Estos elementos se usan para mostrar una gran variedad de tipos diferentes en celdas de tabla, como cadenas, floats, fechas e incluso imágenes, por nombrar algunos. Cada elemento se encarga de mostrar el tipo de datos correctamente. Por ejemplo, un elemento booleano mostrará un switch para alternar su valor. Del mismo modo, un elemento float mostrará un control deslizante para cambiar el valor float.

Hay elementos incluso más complejos para admitir tipos de datos más completos, como imágenes y html. Por ejemplo, un elemento html, que abre un UIWebView para cargar una página web cuando se selecciona, muestra un título en la celda de la tabla.

Trabajar con valores de elemento

Los elementos que se usan para capturar la entrada del usuario exponen una propiedad pública Value que contiene el valor actual del elemento en cualquier momento. Se actualiza automáticamente a medida que el usuario usa la aplicación.

Este es el comportamiento de todos los elementos que forman parte de MonoTouch.Dialog, pero no es necesario para los elementos creados por el usuario.

Elemento de la cadena

Un StringElement muestra un título en el lado izquierdo de una celda de tabla y el valor de cadena en el lado derecho de la celda.

StringElement muestra un título en el lado izquierdo de una celda de tabla y el valor de cadena en el lado derecho de la celda.

Para usar un StringElement como botón, proporcione un delegado.

new StringElement ("Click me", () => { 
    new UIAlertView("Tapped", "String Element Tapped", null, "ok", null).Show();
});

Para usar un stringElement como botón, proporcione un delegado.

Elemento de cadena con estilo

Un StyledStringElement permite presentar cadenas mediante estilos de celda de tabla integrados o con formato personalizado.

Un StyledStringElement permite presentar cadenas mediante estilos de celda de tabla integrados o con formato personalizado

La clase StyledStringElement deriva de StringElement, pero permite a los desarrolladores personalizar una serie de propiedades como fuente, color de texto, color de celda de fondo, modo de salto de línea, número de líneas que se van a mostrar y si se debe mostrar un accesorio.

Elemento multilínea

Elemento multilínea

Elemento de entrada

El EntryElement, como indica el nombre, se usa para obtener la entrada del usuario. Admite cadenas normales o contraseñas, donde los caracteres están ocultos.

EntryElement se usa para obtener la entrada del usuario.

Se inicializa con tres valores:

  • Título de la entrada que se mostrará al usuario.
  • Texto de marcador de posición (este es el texto de color gris que proporciona una sugerencia al usuario).
  • Valor del texto.

El marcador de posición y el valor pueden ser null. Sin embargo, el título es obligatorio.

En cualquier momento, el acceso a su propiedad Value puede recuperar el valor del EntryElement.

Además, la propiedad de KeyboardType se puede establecer en el momento de la creación en el estilo de tipo de teclado deseado para la entrada de datos. Esto se puede usar para configurar el teclado mediante los valores de UIKeyboardType como se muestra a continuación:

  • Numeric
  • Teléfono
  • Url
  • Email

Elemento booleano

Elemento booleano

Elemento de casilla

Elemento de casilla

Elemento de radio

Un RadioElement requiere que se especifique un RadioGroup en el RootElement.

mtRoot = new RootElement ("Demos", new RadioGroup("MyGroup", 0));

Una clase RadioElement requiere que se especifique un RadioGroup en RootElement.

RootElements también se usan para coordinar elementos de radio. Los miembros de RadioElement pueden abarcar varias secciones (por ejemplo, para implementar algo similar al selector de tono de anillo y separar los tonos de anillo personalizados de los tonos del sistema). La vista de resumen mostrará el elemento de radio que está seleccionado actualmente. Para usarlo, cree el RootElement con el constructor de grupo de la siguiente manera:

var root = new RootElement ("Meals", new RadioGroup ("myGroup", 0));

El nombre del grupo de RadioGroup se usa para mostrar el valor seleccionado en la página contenedora (si existe) y el valor, que es cero en este caso, es el índice del primer elemento seleccionado.

Elemento de notificación

Elemento de notificación

Elemento float

Elemento float

Elemento de actividad

Elemento de actividad

Elemento de fecha

Elemento de fecha

Cuando se selecciona la celda correspondiente a DateElement, se presenta un selector de fechas como se muestra a continuación:

Cuando se selecciona la celda correspondiente a DateElement, se presenta un selector de fecha como se muestra.

Elemento Time

Elemento Time

Cuando se selecciona la celda correspondiente a TimeElement, se presenta un selector de hora como se muestra a continuación:

Cuando se selecciona la celda correspondiente a TimeElement, se presenta un selector de hora como se muestra.

Elemento de DateTime

Elemento de DateTime

Cuando se selecciona la celda correspondiente a DateTimeElement, se presenta un selector DateTime como se muestra a continuación:

Cuando se selecciona la celda correspondiente a DateTimeElement, se presenta un selector datetime como se muestra.

Elemento de HTML

Elemento de HTML

HTMLElement muestra el valor de su propiedad deCaption en la celda de tabla. Cuando se seleccione, el Url asignado al elemento se carga en un control UIWebView como se muestra a continuación:

Seleccionado, la dirección URL asignada al elemento se carga en un control UIWebView, como se muestra a continuación.

Elemento de mensaje

Elemento de mensaje

Carga de más elementos

Use este elemento para permitir que los usuarios carguen más elementos en la lista. Puede personalizar los títulos normales y de carga, así como la fuente y el color del texto. El indicador de UIActivity comienza a animar y se muestra el título de carga cuando un usuario pulsa la celda y, a continuación, se ejecuta el NSAction pasado al constructor. Una vez finalizado el código de NSAction, el indicador de UIActivity deja de animarse y se vuelve a mostrar el título normal.

Elemento de UIView

Además, cualquier UIView que se personalice se puede mostrar mediante elUIViewElement.

Elemento de Owner-Drawn

Este elemento debe tener subclases, ya que es una clase abstracta. Debe invalidar el método de Height(RectangleF bounds) en el que debe devolver el alto del elemento, así como Draw(RectangleF bounds, CGContext context, UIView view) en el que debe realizar todo el dibujo personalizado dentro de los límites especificados, utilizando los parámetros de contexto y vista. Este elemento realiza el trabajo pesado de la subclasificación de un UIViewy su colocación en la celda que se va a devolver, dejando que solo necesite implementar dos invalidaciones simples. Puede ver una mejor implementación de ejemplo en la aplicación de ejemplo en el archivo de DemoOwnerDrawnElement.cs.

Este es un ejemplo muy sencillo de implementación de la clase:

public class SampleOwnerDrawnElement : OwnerDrawnElement
{
    public SampleOwnerDrawnElement (string text) : base(UITableViewCellStyle.Default, "sampleOwnerDrawnElement")
    {
        this.Text = text;
    }

    public string Text { get; set; }

    public override void Draw (RectangleF bounds, CGContext context, UIView view)
    {
        UIColor.White.SetFill();
        context.FillRect(bounds);

        UIColor.Black.SetColor();   
        view.DrawString(this.Text, new RectangleF(10, 15, bounds.Width - 20, bounds.Height - 30), UIFont.BoldSystemFontOfSize(14.0f), UILineBreakMode.TailTruncation);
    }

    public override float Height (RectangleF bounds)
    {
        return 44.0f;
    }
}

Elemento de JSON

El JsonElement es una subclase de RootElement que extiende un RootElement para poder cargar el contenido del elemento secundario anidado desde una dirección URL local o remota.

El JsonElement es un RootElement del que se puede crear una instancia en dos formas. Una versión crea un RootElement que cargará el contenido a petición. Estos se crean mediante los constructores de JsonElement que toman un argumento adicional al final, la dirección URL desde la que se carga el contenido:

var je = new JsonElement ("Dynamic Data", "https://tirania.org/tmp/demo.json");

El otro formulario crea los datos a partir de un archivo local o de un existente System.Json.JsonObject que ya ha analizado:

var je = JsonElement.FromFile ("json.sample");
using (var reader = File.OpenRead ("json.sample"))
    return JsonElement.FromJson (JsonObject.Load (reader) as JsonObject, arg);

Para obtener más información sobre el uso de JSON con MT.D, consulte el tutorial del elemento JSON.

Otras características

Compatibilidad con deslizamiento hacia abajo para actualizar

Pull-to- Refresh es un efecto visual que originalmente se encuentra en la aplicación Tweetie2 , que se convirtió en un efecto popular entre muchas aplicaciones.

Para que los cuadros de diálogo sean automáticamente compatibles con el deslizamiento hacia abajo para actualizar, solo tiene que hacer dos cosas: enlazar un controlador de eventos para recibir una notificación cuando el usuario extraiga los datos y notificar a DialogViewController cuando los datos se hayan cargado para volver a su estado predeterminado.

Enlazar una notificación es sencillo; simplemente conéctese al evento de RefreshRequested en el DialogViewController de la siguiente manera:

dvc.RefreshRequested += OnUserRequestedRefresh;

A continuación, en el método OnUserRequestedRefresh, debería poner en cola algunas cargas de datos, solicitar algunos datos de la red o girar un subproceso para calcular los datos. Una vez que se carguen los datos, debe notificar a DialogViewController de que ya están los nuevos datos y restaurar la vista a su estado predeterminado, para ello, llame a ReloadComplete:

dvc.ReloadComplete ();

Compatibilidad con búsquedas

Para admitir la búsqueda, establezca la propiedad de EnableSearch en DialogViewController. También puede establecer la propiedad SearchPlaceholder que se usará como texto de marca de agua en la barra de búsqueda.

La búsqueda cambiará el contenido de la vista a medida que el usuario escribe. Busca en los campos visibles y los muestra al usuario. El DialogViewController expone tres métodos para iniciar, finalizar o desencadenar mediante programación una nueva operación de filtro en los resultados. Estos métodos se muestran a continuación:

  • StartSearch
  • FinishSearch
  • PerformFilter

El sistema es extensible, por lo que puede modificar este comportamiento si lo desea.

Carga de imágenes de fondo

MonoTouch.Dialog incorpora el cargador de imágenes de la aplicación TweetStation. Este cargador de imágenes se puede usar para cargar imágenes en segundo plano, admite el almacenamiento en caché y puede notificar al código cuando se ha cargado la imagen.

También limitará el número de conexiones de red salientes.

El cargador de imágenes se implementa en la clase ImageLoader, lo único que debe hacer es llamar al método DefaultRequestImage. Deberá proporcionar el URI para la imagen que desea cargar, así como una instancia de la interfaz de IImageUpdated que se invocará cuando se haya cargado la imagen.

Por ejemplo, el código siguiente carga una imagen de una dirección URL en un BadgeElement:

string uriString = "http://some-server.com/some image url";

var rootElement = new RootElement("Image Loader") {
    new Section() {
        new BadgeElement( ImageLoader.DefaultRequestImage( new Uri(uriString), this), "Xamarin")
    }
};

La clase ImageLoader expone un método Purgar al que puede llamar cuando desee liberar todas las imágenes que están almacenadas actualmente en caché en la memoria. El código actual tiene una memoria caché para 50 imágenes. Si desea usar un tamaño de caché diferente (por ejemplo, si espera que las imágenes sean demasiado grandes de modo que 50 imágenes serían demasiado), puede crear instancias de ImageLoader y pasar el número de imágenes que desea guardar en la memoria caché.

Uso de LINQ para crear una jerarquía de elementos

Mediante el uso inteligente de la sintaxis de inicialización de C# y LINQ, LINQ se puede usar para crear una jerarquía de elementos. Por ejemplo, el código siguiente crea una pantalla a partir de algunas matrices de cadenas y controla la selección de celdas a través de una función anónima que se pasa a cada StringElement:

var rootElement = new RootElement ("LINQ root element") {
    from x in new string [] { "one", "two", "three" }
    select new Section (x) {
        from y in "Hello:World".Split (':')
        select (Element) new StringElement (y, delegate { Debug.WriteLine("cell tapped"); })
    }
};

Esto se podría combinar fácilmente con un almacén de datos XML o datos de una base de datos para crear aplicaciones complejas casi por completo a partir de datos.

Extensión de MT.D

Creación de elementos personalizados

Puede crear su propio elemento heredando de un elemento existente o derivando de la clase raíz Element.

Para crear su propio elemento, querrá invalidar los métodos siguientes:

// To release any heavy resources that you might have
void Dispose (bool disposing);

// To retrieve the UITableViewCell for your element
// you would need to prepare the cell to be reused, in the
// same way that UITableView expects reusable cells to work
UITableViewCell GetCell (UITableView tv);

// To retrieve a "summary" that can be used with
// a root element to render a summary one level up.  
string Summary ();

// To detect when the user has tapped on the cell
void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path);

// If you support search, to probe if the cell matches the user input
bool Matches (string text);

Si el elemento puede tener un tamaño variable, debe implementar la interfaz IElementSizing, que contiene un método:

// Returns the height for the cell at indexPath.Section, indexPath.Row
float GetHeight (UITableView tableView, NSIndexPath indexPath);

Si planea implementar el GetCell método llamando a base.GetCell(tv) y personalizando la celda devuelta, también debe invalidar la propiedad CellKey para devolver una clave que será única para el elemento, de la siguiente manera:

static NSString MyKey = new NSString ("MyKey");
protected override NSString CellKey {
    get {
        return MyKey;
    }
}

Esto funciona para la mayoría de los elementos, pero no para StringElement y StyledStringElement ya que usan su propio conjunto de claves para diversos escenarios de representación. Tendría que replicar el código en esas clases.

DialogViewControllers (DVC)

Tanto la API Reflection como Elements usan el mismo DialogViewController. A veces, querrá personalizar el aspecto de la vista o puede que quiera usar algunas características del UITableViewController que van más allá de la creación básica de interfaces de usuario.

El DialogViewController es simplemente una subclase de UITableViewController y puede personalizarlo de la misma manera que personalizaría un UITableViewController.

Por ejemplo, si desea cambiar el estilo de lista para que sea Grouped o Plain, puede establecer este valor cambiando la propiedad al crear el controlador, de la siguiente manera:

var myController = new DialogViewController (root, true) {
    Style = UITableViewStyle.Grouped;
}

Para disfrutar de personalizaciones más avanzadas de DialogViewController, como establecer su fondo, podría crear subclases e invalidar los métodos adecuados, como se muestra en el ejemplo siguiente:

class SpiffyDialogViewController : DialogViewController {
    UIImage image;

    public SpiffyDialogViewController (RootElement root, bool pushing, UIImage image) 
        : base (root, pushing) 
    {
        this.image = image;
    }

    public override LoadView ()
    {
        base.LoadView ();
        var color = UIColor.FromPatternImage(image);
        TableView.BackgroundColor = UIColor.Clear;
        ParentViewController.View.BackgroundColor = color;
    }
}

Otro punto de personalización es los siguientes métodos virtuales de DialogViewController:

public override Source CreateSizingSource (bool unevenRows)

Este método debe devolver una subclase de DialogViewController.Source para los casos en los que las celdas tienen un tamaño uniforme o una subclase de DialogViewController.SizingSource si las celdas son desiguales.

Puede usar esta invalidación para capturar cualquiera de los métodos de UITableViewSource. Por ejemplo, TweetStation usa esto para realizar un seguimiento de cuándo el usuario se desplaza a la parte superior y actualizar en consecuencia el número de tweets no leídos.

Validation

Los elementos no proporcionan validación ellos mismos, ya que los modelos que son adecuados para las páginas web y las aplicaciones de escritorio no se asignan directamente al modelo de interacción de iPhone.

Si desea realizar la validación de datos, debe hacerlo cuando el usuario desencadena una acción con los datos especificados. Por ejemplo, un botón Listo o Siguiente en la barra de herramientas superior, o algunos StringElement que se usan como botón para ir a la siguiente fase.

Aquí es donde realizaría la validación de entrada básica y quizás una validación más complicada, como comprobar la validez de una combinación de usuario y contraseña con un servidor.

La forma en que se notifica al usuario de un error es específica de la aplicación. Podría abrir un elemento emergente de UIAlertView o mostrar una sugerencia.

Resumen

En este artículo se ha abordado una gran cantidad de información sobre MonoTouch.Dialog. Se han analizado los aspectos básicos de la forma en que MT.D funciona y abarca los distintos componentes que componen MT.D. También mostró la amplia matriz de elementos y personalizaciones de tabla compatibles con MT.D y se ha analizado cómo MT.D se puede extenderse con elementos personalizados. Además, ha explicado la compatibilidad con JSON en MT.D que permite crear elementos dinámicamente a partir de JSON.