Introdução ao MonoTouch.Dialog para Xamarin.iOS
MonoTouch.Dialog, conhecido como MT. D para abreviar, é um kit de ferramentas de desenvolvimento rápido de interface do usuário que permite aos desenvolvedores criar telas de aplicativos e navegação usando informações, em vez do tédio de criar controladores de exibição, tabelas etc. Como tal, ele fornece uma simplificação significativa do desenvolvimento da interface do usuário e da redução de código. Por exemplo, considere a seguinte captura de tela:
O seguinte código foi usado para definir essa tela inteira:
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;
}
Ao trabalhar com tabelas no iOS, geralmente há uma tonelada de código repetitivo. Por exemplo, toda vez que uma tabela é necessária, uma fonte de dados é necessária para preencher essa tabela. Em um aplicativo que tem duas telas baseadas em tabela conectadas por meio de um controlador de navegação, cada tela compartilha muito do mesmo código.
MT. D simplifica isso encapsulando todo esse código em uma API genérica para criação de tabelas. Em seguida, ele fornece uma abstração sobre essa API que permite uma sintaxe de associação de objeto declarativa que torna isso ainda mais fácil. Dessa forma, há duas APIs disponíveis no MT. D:
- API de elementos de baixo nível – A API de elementos é baseada na criação de uma árvore hierárquica de elementos que representam telas e seus componentes. A API Elements oferece aos desenvolvedores mais flexibilidade e controle na criação de interfaces do usuário. Além disso, a API Elements tem suporte avançado para definição declarativa via JSON, o que permite uma declaração incrivelmente rápida, bem como a geração dinâmica de interface do usuário a partir de um servidor.
- API de reflexão de alto nível – Também conhecida como API de associação, na qual as classes são anotadas com dicas de interface do usuário e, em seguida, MT. D cria telas automaticamente com base nos objetos e fornece uma ligação entre o que é exibido (e opcionalmente editado) na tela e o suporte do objeto subjacente. O exemplo acima ilustrou o uso da API de reflexão. Essa API não fornece o controle refinado que a API de elementos fornece, mas reduz ainda mais a complexidade criando automaticamente a hierarquia de elementos com base em atributos de classe.
MT. D vem com um grande conjunto de elementos de interface do usuário integrados para criação de tela, mas também reconhece a necessidade de elementos personalizados e layouts de tela avançados. Dessa forma, a extensibilidade é um recurso de primeira classe incorporado à API. Os desenvolvedores podem estender os elementos existentes ou criar novos e depois integrá-los perfeitamente.
Além disso, MT. D tem vários recursos comuns de UX do iOS integrados, como suporte "pull-to-refresh", carregamento assíncrono de imagens e suporte a pesquisa.
Este artigo analisará de forma abrangente o trabalho com MT. D, incluindo:
- MT. Componentes D – Isso se concentrará na compreensão das classes que compõem o MT. D para permitir a rápida aceleração.
- Referência de elementos – Uma lista abrangente dos elementos integrados do MT.D.
- Uso avançado – abrange recursos avançados, como pull to refresh, pesquisa, carregamento de imagem de fundo, uso do LINQ para criar hierarquias de elementos e criação de elementos, células e controladores personalizados para uso com o MT.D.
Configurando o MT. D
MT. D é distribuído com o Xamarin.iOS. Para usá-lo, clique com o botão direito do mouse no nó Referências de um projeto Xamarin.iOS no Visual Studio 2017 ou Visual Studio para Mac e adicione uma referência ao assembly MonoTouch.Dialog-1 . Em seguida, adicione using MonoTouch.Dialog
instruções em seu código-fonte conforme necessário.
Entendendo as peças do MT. D
Mesmo ao usar a API de reflexão, o MT. D cria uma hierarquia de elementos nos bastidores, como se ela tivesse sido criada diretamente por meio da API de elementos. Além disso, o suporte JSON mencionado na seção anterior também cria elementos. Por esse motivo, é importante ter uma compreensão básica das partes constituintes do MT.D.
MT. D constrói telas usando as quatro partes a seguir:
- DialogViewController
- RootElement
- Seção
- Element
DialogViewController
Um DialogViewController, ou DVC , herda e UITableViewController
, portanto, representa uma tela com uma tabela. Os DVCs podem ser enviados por push para um controlador de navegação como um UITableViewController normal.
RootElement
Um RootElement é o contêiner de nível superior para os itens que entram em um DVC. Ele contém seções, que podem conter elementos. RootElements não são renderizados; em vez disso, eles são simplesmente contêineres para o que realmente é renderizado. Um RootElement é atribuído a um DVC e, em seguida, o DVC renderiza seus filhos.
Seção
Uma seção é um grupo de células em uma tabela. Assim como acontece com uma seção de tabela normal, ela pode opcionalmente ter um cabeçalho e rodapé que podem ser texto ou até mesmo exibições personalizadas, como na captura de tela a seguir:
Element
Um elemento representa uma célula real na tabela. MT. D vem com uma ampla variedade de elementos que representam diferentes tipos de dados ou entradas diferentes. Por exemplo, as capturas de tela a seguir ilustram alguns dos elementos disponíveis:
Mais sobre seções e RootElements
Vamos agora discutir RootElements e Sections com mais detalhes.
Elementos de raiz
Pelo menos um RootElement é necessário para iniciar o processo MonoTouch.Dialog.
Se um RootElement for inicializado com um valor de seção/elemento, esse valor será usado para localizar um Element filho que fornecerá um resumo da configuração, que é renderizado no lado direito da exibição. Por exemplo, a captura de tela abaixo mostra uma tabela à esquerda com uma célula contendo o título da tela de detalhes à direita, "Sobremesa", junto com o valor da sobremesa selecionada.
Os elementos raiz também podem ser usados dentro de Seções para disparar o carregamento de uma nova página de configuração aninhada, conforme mostrado acima. Quando usado neste modo, a legenda fornecida é usada enquanto renderizada dentro de uma seção e também é usada como título da subpágina. Por exemplo:
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")
}
}
}
};
No exemplo acima, quando o usuário toca em "Sobremesa", MonoTouch.Dialog cria uma nova página e navega até ela com a raiz sendo "Sobremesa" e tendo um grupo de opções com três valores.
Neste exemplo específico, o grupo de rádio selecionará "Bolo de Chocolate" na seção "Sobremesa" porque passamos o valor "2" para o RadioGroup. Isso significa escolher o 3º item da lista (índice zero).
Chamar o método Add ou usar a sintaxe do inicializador C# 4 adiciona seções. Os métodos Insert são fornecidos para inserir seções com uma animação.
Se você criar o RootElement com uma instância de Group (em vez de um RadioGroup), o valor de resumo do RootElement quando exibido em uma Section será a contagem cumulativa de todos os BooleanElements e CheckboxElements que têm a mesma chave que o valor Group.Key.
Seções
As seções são usadas para agrupar elementos na tela e são os únicos filhos diretos válidos do RootElement. As seções podem conter qualquer um dos elementos padrão, incluindo novos RootElements.
RootElements inseridos em uma seção são usados para navegar para um novo nível mais profundo.
As seções podem ter cabeçalhos e rodapés como cadeias de caracteres ou como UIViews. Normalmente, você usará apenas as cadeias de caracteres, mas para criar interfaces do usuário personalizadas, você pode usar qualquer UIView como cabeçalho ou rodapé. Você pode usar uma string para criá-los assim:
var section = new Section ("Header", "Footer");
Para usar views, basta passar as views para o construtor:
var header = new UIImageView (Image.FromFile ("sample.png"));
var section = new Section (header);
Ser notificado
Manipulando NSAction
MT. D exibe an NSAction
como um delegado para lidar com retornos de chamada.
Por exemplo, digamos que você queira manipular um evento de toque para uma célula de tabela criada por MT.D. Ao criar um elemento com MT. D, basta fornecer uma função de retorno de chamada, conforme mostrado abaixo:
new Section () {
new StringElement ("Demo Callback", delegate { Console.WriteLine ("Handled"); })
}
Recuperando o valor do elemento
Combinado com a Element.Value
propriedade, o retorno de chamada pode recuperar o valor definido em outros elementos. Por exemplo, considere o seguinte 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); })
}
};
Esse código cria uma interface do usuário, conforme mostrado abaixo. Para obter um passo a passo completo deste exemplo, consulte o tutorial Passo a passo da API do Elements.
Quando o usuário pressiona a célula da tabela inferior, o código na função anônima é executado, gravando o valor da instância no painel Saída element
do Aplicativo no Visual Studio para Mac.
Elementos integrados
MT. D vem com vários itens de célula de tabela integrados conhecidos como Elementos. Esses elementos são usados para exibir uma variedade de tipos diferentes em células de tabela, como strings, floats, datas e até imagens, para citar apenas alguns. Cada elemento se encarrega de exibir o tipo de dados adequadamente. Por exemplo, um elemento booleano exibirá uma opção para alternar seu valor. Da mesma forma, um elemento float exibirá um controle deslizante para alterar o valor float.
Existem elementos ainda mais complexos para dar suporte a tipos de dados mais avançados, como imagens e html. Por exemplo, um elemento html, que abrirá um UIWebView para carregar uma página da Web quando selecionado, exibe uma legenda na célula da tabela.
Trabalhando com valores de elemento
Os elementos usados para capturar a entrada do usuário expõem uma propriedade pública Value
que contém o valor atual do elemento a qualquer momento. Ele é atualizado automaticamente à medida que o usuário usa o aplicativo.
Esse é o comportamento de todos os elementos que fazem parte de MonoTouch.Dialog, mas não é necessário para elementos criados pelo usuário.
Elemento de cadeia de caracteres
A StringElement
mostra uma legenda no lado esquerdo de uma célula da tabela e o valor da cadeia de caracteres no lado direito da célula.
Para usar a StringElement
como um botão, forneça um delegado.
new StringElement ("Click me", () => {
new UIAlertView("Tapped", "String Element Tapped", null, "ok", null).Show();
});
Elemento de cadeia de caracteres estilizado
A StyledStringElement
permite que as cadeias de caracteres sejam apresentadas usando estilos de célula de tabela internos ou com formatação personalizada.
A StyledStringElement
classe deriva de StringElement
, mas permite que os desenvolvedores personalizem algumas propriedades, como Font, cor do texto, cor da célula de fundo, modo de quebra de linha, número de linhas a serem exibidas e se um acessório deve ser exibido.
Elemento multilinha
Elemento de entrada
O EntryElement
, como o nome indica, é usado para obter a entrada do usuário. Ele suporta strings regulares ou senhas, onde os caracteres estão ocultos.
Ele é inicializado com três valores:
- A legenda da entrada que será mostrada ao usuário.
- Texto de espaço reservado (este é o texto acinzentado que fornece uma dica para o usuário).
- O valor do texto.
O espaço reservado e o valor podem ser nulos. No entanto, a legenda é obrigatória.
A qualquer momento, acessar sua propriedade Value pode recuperar o valor do EntryElement
.
Além disso, a propriedade pode ser definida no momento da KeyboardType
criação para o estilo de tipo de teclado desejado para a entrada de dados. Isso pode ser usado para configurar o teclado usando os valores listados UIKeyboardType
abaixo:
- Numérico
- Telefone
- Url
Elemento booleano
Elemento de caixa de seleção
Elemento de rádio
A RadioElement
requer que a RadioGroup
seja especificado no RootElement
.
mtRoot = new RootElement ("Demos", new RadioGroup("MyGroup", 0));
RootElements
também são usados para coordenar elementos de rádio. Os RadioElement
membros podem abranger várias seções (por exemplo, para implementar algo semelhante ao seletor de toque e separar toques personalizados dos toques do sistema). A visualização de resumo mostrará o elemento de rádio selecionado no momento. Para usar isso, crie o RootElement
com o construtor do grupo, assim:
var root = new RootElement ("Meals", new RadioGroup ("myGroup", 0));
O nome do grupo em RadioGroup
é usado para mostrar o valor selecionado na página que o contém (se houver) e o valor, que é zero neste caso, é o índice do primeiro item selecionado.
Elemento de emblema
Elemento flutuante
Elemento de atividade
Elemento de data
Quando a célula correspondente ao DateElement é selecionada, um seletor de data é apresentado conforme mostrado abaixo:
Elemento Time
Quando a célula correspondente ao TimeElement é selecionada, um seletor de tempo é apresentado conforme mostrado abaixo:
Elemento DateTime
Quando a célula correspondente ao DateTimeElement é selecionada, um seletor de data e hora é apresentado conforme mostrado abaixo:
Elemento HTML
O HTMLElement
exibe o valor de sua Caption
propriedade na célula da tabela. Quando selecionado, o Url
atribuído ao elemento é carregado em um UIWebView
controle, conforme mostrado abaixo:
Elemento Message
Carregar mais elemento
Use esse elemento para permitir que os usuários carreguem mais itens em sua lista. Você pode personalizar as legendas normais e de carregamento, bem como a fonte e a cor do texto.
O UIActivity
indicador começa a animar e a legenda de carregamento é exibida quando um usuário toca na célula e, em seguida, o NSAction
passado para o construtor é executado. Depois que o código estiver concluído NSAction
, o UIActivity
indicador para de animar e a legenda normal é exibida novamente.
Elemento UIView
Além disso, qualquer costume UIView
pode ser exibido usando o UIViewElement
.
Elemento desenhado pelo proprietário
Este elemento deve ser subclassificado, pois é uma classe abstrata. Você deve substituir o Height(RectangleF bounds)
método no qual você deve retornar a altura do elemento, bem Draw(RectangleF bounds, CGContext context, UIView view)
como no qual você deve fazer todo o seu desenho personalizado dentro dos limites fornecidos, usando os parâmetros de contexto e vista. Este elemento faz o trabalho pesado de subclasse a UIView
, e colocá-lo na célula a ser retornada, deixando você apenas precisando implementar duas substituições simples. Você pode ver uma implementação de exemplo melhor no aplicativo de exemplo no DemoOwnerDrawnElement.cs
arquivo.
Aqui está um exemplo muito simples de implementação da classe:
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 JSON
O JsonElement
é uma subclasse de RootElement
que estende a para RootElement
poder carregar o conteúdo do filho aninhado de um url local ou remoto.
O JsonElement
é um RootElement
que pode ser instanciado de duas formas. Uma versão cria um RootElement
que carregará o conteúdo sob demanda. Eles são criados usando os JsonElement
construtores que recebem um argumento extra no final, a url para carregar o conteúdo:
var je = new JsonElement ("Dynamic Data", "https://tirania.org/tmp/demo.json");
O outro formulário cria os dados de um arquivo local ou de um existente System.Json.JsonObject
que você já analisou:
var je = JsonElement.FromFile ("json.sample");
using (var reader = File.OpenRead ("json.sample"))
return JsonElement.FromJson (JsonObject.Load (reader) as JsonObject, arg);
Para obter mais informações sobre como usar JSON com MT. D, consulte o tutorial Passo a passo do elemento JSON.
Outros recursos
Suporte Pull-to-Refresh
Pull-to-Refresh é um efeito visual originalmente encontrado no aplicativo Tweetie2, que se tornou um efeito popular entre muitos aplicativos.
Para adicionar suporte automático de puxar para atualizar às suas caixas de diálogo, você só precisa fazer duas coisas: conectar um manipulador de eventos para ser notificado quando o usuário extrair os dados e notificar quando DialogViewController
os dados forem carregados para voltar ao seu estado padrão.
Conectar uma notificação é simples; Basta conectar-se ao RefreshRequested
evento no DialogViewController
, assim:
dvc.RefreshRequested += OnUserRequestedRefresh;
Em seguida, em seu método OnUserRequestedRefresh
, você enfileiraria alguns carregamentos de dados, solicitaria alguns dados da rede ou giraria um thread para calcular os dados. Depois que os dados forem carregados, você deverá notificar o DialogViewController
de que os novos dados estão e, para restaurar a exibição ao seu estado padrão, faça isso chamando ReloadComplete
:
dvc.ReloadComplete ();
Pesquisar Suporte
Para dar suporte à pesquisa, defina a EnableSearch
propriedade em seu DialogViewController
arquivo . Você também pode definir a SearchPlaceholder
propriedade a ser usada como texto de marca d'água na barra de pesquisa.
A pesquisa alterará o conteúdo da exibição à medida que o usuário digita. Ele pesquisa os campos visíveis e os mostra ao usuário. O DialogViewController
expõe três métodos para iniciar, encerrar ou disparar programaticamente uma nova operação de filtro nos resultados. Esses métodos estão listados abaixo:
StartSearch
FinishSearch
PerformFilter
O sistema é extensível, portanto, você pode alterar esse comportamento, se desejar.
Carregamento da imagem de fundo
O MonoTouch.Dialog incorpora o carregador de imagens do aplicativo TweetStation . Esse carregador de imagens pode ser usado para carregar imagens em segundo plano, suporta cache e pode notificar seu código quando a imagem for carregada.
Também limitará o número de conexões de rede de saída.
O carregador de imagens é implementado na classe, tudo o ImageLoader
que você precisa fazer é chamar o DefaultRequestImage
método, você precisará fornecer o Uri para a imagem que deseja carregar, bem como uma instância da interface que será invocada IImageUpdated
quando a imagem for carregada.
Por exemplo, o código a seguir carrega uma imagem de uma URL em um 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")
}
};
A classe ImageLoader expõe um método Purge que você pode chamar quando quiser liberar todas as imagens que estão atualmente armazenadas em cache na memória. O código atual tem um cache para 50 imagens. Se você quiser usar um tamanho de cache diferente (por exemplo, se você espera que as imagens sejam muito grandes, 50 imagens seriam demais), basta criar instâncias do ImageLoader e passar o número de imagens que deseja manter no cache.
Usando o LINQ para criar hierarquia de elementos
Por meio do uso inteligente da sintaxe de inicialização do LINQ e do C#, o LINQ pode ser usado para criar uma hierarquia de elementos. Por exemplo, o código a seguir cria uma tela a partir de algumas matrizes de cadeia de caracteres e manipula a seleção de células por meio de uma função anônima que é passada para 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"); })
}
};
Isso pode ser facilmente combinado com um armazenamento de dados XML ou dados de um banco de dados para criar aplicativos complexos quase inteiramente a partir de dados.
Estendendo o MT. D
Criando elementos personalizados
Você pode criar seu próprio elemento herdando de um Element existente ou derivando da classe raiz Element.
Para criar seu próprio elemento, você desejará substituir os seguintes métodos:
// 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);
Se o elemento puder ter um tamanho variável, você precisará implementar a IElementSizing
interface, que contém um método:
// Returns the height for the cell at indexPath.Section, indexPath.Row
float GetHeight (UITableView tableView, NSIndexPath indexPath);
Se você estiver planejando implementar seu GetCell
método chamando base.GetCell(tv)
e personalizando a célula retornada, também precisará substituir a CellKey
propriedade para retornar uma chave que será exclusiva para seu Element, desta forma:
static NSString MyKey = new NSString ("MyKey");
protected override NSString CellKey {
get {
return MyKey;
}
}
Isso funciona para a maioria dos elementos, mas não para o StringElement
e StyledStringElement
como eles usam seu próprio conjunto de chaves para vários cenários de renderização. Você teria que replicar o código nessas classes.
DialogViewControllers (DVCs)
Tanto a API Reflection quanto a Elements usam o mesmo DialogViewController
. Às vezes, você desejará personalizar a aparência do modo de exibição ou talvez queira usar alguns recursos do UITableViewController
que vão além da criação básica de interfaces do usuário.
O DialogViewController
é apenas uma subclasse do UITableViewController
e você pode personalizá-lo da mesma forma que personalizaria um UITableViewController
.
Por exemplo, se você quiser alterar o estilo de lista para ou Grouped
Plain
, poderá definir esse valor alterando a propriedade ao criar o controlador, desta forma:
var myController = new DialogViewController (root, true) {
Style = UITableViewStyle.Grouped;
}
Para personalizações mais avançadas do DialogViewController
, como definir seu plano de fundo, você deve subclassificá-lo e substituir os métodos adequados, conforme mostrado no exemplo abaixo:
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;
}
}
Outro ponto de personalização são os seguintes métodos virtuais no DialogViewController
:
public override Source CreateSizingSource (bool unevenRows)
Esse método deve retornar uma subclasse de para casos em DialogViewController.Source
que suas células são de tamanho uniforme ou uma subclasse de DialogViewController.SizingSource
se suas células são desiguais.
Você pode usar essa substituição para capturar qualquer um dos UITableViewSource
métodos. Por exemplo, o TweetStation usa isso para rastrear quando o usuário rolou para o topo e atualizar de acordo com o número de tweets não lidos.
Validação
Os elementos não fornecem validação por conta própria, pois os modelos adequados para páginas da Web e aplicativos de desktop não são mapeados diretamente para o modelo de interação do iPhone.
Se você quiser fazer a validação de dados, deverá fazer isso quando o usuário acionar uma ação com os dados inseridos. Por exemplo, um botão Concluído ou Avançar na barra de ferramentas superior, ou alguns StringElement
usados como um botão para ir para o próximo estágio.
É aqui que você executaria a validação básica de entrada e talvez a validação mais complicada, como verificar a validade de uma combinação de usuário/senha com um servidor.
A forma como você notifica o usuário sobre um erro é específica do aplicativo. Você pode abrir um UIAlertView
ou mostrar uma dica.
Resumo
Este artigo abordou muitas informações sobre o MonoTouch.Dialog. Ele discutiu os fundamentos de como o MT. D e cobriu os vários componentes que compõem o MT.D. Ele também mostrou a grande variedade de elementos e personalizações de tabela suportados pelo MT. D e discutiu como MT. D pode ser estendido com elementos personalizados. Além disso, explicou o suporte a JSON no MT. D que permite criar elementos dinamicamente a partir de JSON.
Links relacionados
- Passo a passo: criar um aplicativo usando a API de elementos
- Passo a passo: criar um aplicativo usando a API de reflexão
- Passo a passo: usar um elemento JSON para criar uma interface do usuário
- Marcação JSON MonoTouch.Dialog
- Caixa de diálogo MonoTouch no Github
- Referência da classe UITableViewController
- Referência de classe UINavigationController