Storyboards no Xamarin.iOS
Neste guia, explicaremos o que é um Storyboard e examinaremos alguns dos principais componentes, como Segues. Veremos como os Storyboards podem ser criados e usados e quais vantagens eles têm para um desenvolvedor.
Antes que o formato de arquivo Storyboard fosse introduzido pela Apple como uma representação visual da interface do usuário de um aplicativo iOS, os desenvolvedores criavam arquivos XIB para cada controlador de exibição e programavam a navegação entre cada exibição manualmente. O uso de um Storyboard permite que o desenvolvedor defina os controladores de exibição e a navegação entre eles em uma superfície de design e oferece edição WYSIWYG da interface do usuário do aplicativo.
Um Storyboard pode ser criado e aberto com Visual Studio para Mac. Este guia também explicará como usar o Construtor de Interface do Xcode para criar seus storyboards enquanto usa C# para programar a navegação.
Requisitos
Os storyboards podem ser usados com o Xcode e iniciados de dentro de um projeto Xamarin.iOS no Visual Studio para Mac.
O que é um Storyboard?
Um Storyboard é a representação visual de todas as telas em um aplicativo. Ele contém uma sequência de cenas, com cada cena representando um Controlador de Exibição e seus Modos de Exibição. Essas exibições podem conter objetos e controles que permitem que o usuário interaja com seu aplicativo. Essa coleção de exibições e controles (ou subexibições) é conhecida como Hierarquia de Exibição de Conteúdo. As cenas são conectadas por objetos segue, que representam uma transição entre os controladores de exibição. Isso normalmente é obtido criando uma transição entre um objeto na visualização inicial e a visualização de conexão. As relações na superfície de design são ilustradas na imagem a seguir:
Conforme mostrado, o storyboard apresenta cada uma de suas cenas com conteúdo já renderizado e ilustra as conexões entre elas. Quando falamos de cenas em um iPhone, é seguro assumir que uma cena no storyboard é igual a uma tela de conteúdo no dispositivo. No entanto, com um iPad, é possível que várias cenas apareçam ao mesmo tempo, por exemplo, usando um controlador de exibição Popover.
Há muitas vantagens em usar storyboards para criar a interface do usuário do aplicativo, especialmente ao usar o Xamarin. Em primeiro lugar, é uma representação visual da interface do usuário, pois todos os objetos – incluindo controles personalizados – são renderizados em tempo de design. Isso significa que, antes de criar ou implantar seu aplicativo, você pode visualizar sua aparência e fluxo. Veja a imagem anterior, por exemplo. Podemos dizer, a partir de uma rápida olhada na superfície de design, quantas cenas existem, o layout de cada exibição e como tudo está relacionado. Isso é o que torna os Storyboards tão poderosos.
Você também pode gerenciar eventos com Storyboards. A maioria dos controles de interface do usuário tem uma lista de eventos possíveis no Painel de Propriedades. O manipulador de eventos pode ser adicionado aqui e concluído em um método parcial na classe View Controllers.
O conteúdo de um storyboard é armazenado como um arquivo XML. No momento da compilação, todos os .storyboard
arquivos são compilados em arquivos binários conhecidos como nibs. Em tempo de execução, essas nibs são inicializadas e instanciadas para criar novas visualizações.
Segues
Um Segue, ou Segue Object, é usado no desenvolvimento do iOS para representar uma transição entre cenas. Para criar uma sequência, mantenha pressionada a tecla Ctrl e clique e arraste de uma cena para outra. Conforme você arrasta o mouse, aparece um conector azul que indica para onde a sequência levará. Isso é mostrado na imagem a seguir:
Ao passar o mouse, aparece um menu que permite escolher a ação para o segue. Pode ser semelhante às seguintes imagens:
Pré-iOS 8 e classes de tamanho:
Ao usar classes de tamanho e sequências adaptativas:
Importante
Se você estiver usando o VMWare para sua máquina virtual do Windows, clique com a tecla Ctrl pressionada como o botão direito do mouse por padrão. Para criar um Segue, edite suas preferências de teclado por meio de Preferências>, Atalhos de teclado e mouse>e remapeie o botão Secundário, conforme ilustrado abaixo:
Agora você deve ser capaz de adicionar uma transição entre seus controladores de exibição normalmente.
Há diferentes tipos de transições, cada uma dando controle sobre como um novo controlador de exibição é apresentado ao usuário e como ele interage com outros controladores de exibição no Storyboard. Eles são explicados abaixo. Também é possível subclasse de um objeto segue para implementar uma transição personalizada:
Mostrar / Enviar – Uma sequência de push adiciona o controlador de exibição à pilha de navegação. Ele pressupõe que o controlador de exibição que origina o push faz parte do mesmo controlador de navegação que o controlador de exibição que está sendo adicionado à pilha. Isso faz a mesma coisa que
pushViewController
, e geralmente é usado quando há alguma relação entre os dados nas telas. O uso do push segue oferece o luxo de ter uma barra de navegação com um botão Voltar e um título adicionados a cada exibição na pilha, permitindo a navegação detalhada pela hierarquia de exibição.Modal – Uma sequência modal cria uma relação entre dois controladores de exibição em seu projeto, com a opção de mostrar uma transição animada. O controlador de exibição filho obscurecerá completamente o controlador de exibição pai quando for exibido. Ao contrário de um push segue, que adiciona um botão Voltar para nós, você deve usar um
DismissViewController
ao usar um segue modal para retornar ao controlador de exibição anterior.Personalizado – Qualquer segue personalizado pode ser criado como uma subclasse de
UIStoryboardSegue
.Desenrolar – uma sequência de desenrolamento pode ser usada para navegar de volta por meio de um push ou sequência modal, por exemplo, descartando o controlador de exibição apresentado modalmente. Além disso, você pode desenrolar não apenas uma, mas uma série de sequências de push e modais e voltar várias etapas em sua hierarquia de navegação com uma única ação de desenrolamento. Para entender como usar um desenrolar segue no iOS, leia a receita Criando desenrolar segues .
Sem origem – Um segue sem origem indica a cena que contém o controlador de exibição inicial e, portanto, qual exibição o usuário verá primeiro. É representado pela sequência mostrada aqui:
Tipos de Segue Adaptável
O iOS 8 introduziu classes de tamanho para permitir que um arquivo de storyboard do iOS funcione com todos os tamanhos de tela disponíveis, permitindo que os desenvolvedores criem uma interface do usuário para todos os dispositivos iOS. Por padrão, todos os novos aplicativos Xamarin.iOS usam classes de tamanho. Para usar classes de tamanho de um projeto mais antigo, consulte o guia Introdução aos Storyboards Unificados .
Qualquer aplicativo que use classes de tamanho também usará o novo Adaptive Segues. Ao usar classes de tamanho, lembre-se de que você não está especificando diretamente se está usando um iPhone ou iPad. Em outras palavras, você está criando uma interface do usuário que sempre terá a mesma aparência, independentemente de quanto espaço ela tenha para trabalhar. As Sequências Adaptativas funcionam julgando o ambiente e determinando a melhor forma de apresentar o conteúdo. Os Segues Adaptativos são mostrados abaixo:
Segue | Descrição |
---|---|
Mostrar | Isso é muito semelhante a um Push segue, mas leva em consideração o conteúdo da tela. |
Mostrar Detalhes | Se o aplicativo exibir uma exibição mestre e de detalhes (por exemplo, em um controlador de exibição dividida em um iPad), o conteúdo substituirá a exibição de detalhes. Se o aplicativo exibir apenas o mestre ou o detalhe, o conteúdo substituirá a parte superior da pilha do controlador de exibição. |
Apresentação | Isso é semelhante ao Modal segue e permite a seleção de estilos de apresentação e transição. |
Apresentação Popover | Isso apresenta o conteúdo como um popover. |
Transferência de dados com Segues
Os benefícios de uma sequência não terminam com transições. Eles também podem ser usados para gerenciar a transferência de dados entre controladores de exibição. Isso é obtido substituindo o PrepareForSegue
método no controlador de exibição inicial e manipulando os dados por conta própria. Quando o segue é disparado – por exemplo, com um pressionamento de botão – o aplicativo chamará esse método, fornecendo uma oportunidade de preparar o novo controlador de exibição antes que ocorra qualquer navegação. O código a seguir demonstra isso:
public override void PrepareForSegue (UIStoryboardSegue segue,
NSObject sender)
{
base.PrepareForSegue (segue, sender);
var callHistoryController = segue.DestinationViewController
as CallHistoryController;
if (callHistoryController != null) {
callHistoryController.PhoneNumbers = PhoneNumbers;
}
}
Neste exemplo, o PrepareForSegue
método será chamado quando o segue for disparado pelo usuário. Primeiro, você deve criar uma instância do controlador de exibição 'receptor' e defini-la como o Controlador de exibição de destino do segue. Isso é feito pela linha de código abaixo:
var callHistoryController = segue.DestinationViewController as CallHistoryController;
O método agora tem a capacidade de definir propriedades no DestinationViewController
. Este exemplo aproveita essa capacidade passando uma lista chamada PhoneNumbers
para o CallHistoryController
e atribuindo-a a um objeto com o mesmo nome:
if (callHistoryController != null) {
callHistoryController.PhoneNumbers = PhoneNumbers;
}
Assim que a transição for concluída, o usuário verá o CallHistoryController
com a lista preenchida.
Adicionando um Storyboard a um Projeto que Não Faz Storyboard
Ocasionalmente, talvez seja necessário adicionar um Storyboard a um arquivo que não era de storyboard anteriormente. Você pode simplificar o processo no Visual Studio para Mac seguindo estas etapas:
Crie um novo arquivo de Storyboard navegando até Arquivo > Novo Arquivo > iOS > Storyboard.
Adicione o nome do Storyboard à seção Interface Principal do Info.plist.
Isso faz o equivalente a instanciar o Controlador de Exibição Inicial no
FinishedLaunching
método dentro do Delegado do Aplicativo. Com essa opção definida, o aplicativo instancia uma janela (consulte a próxima etapa), carrega o storyboard principal e atribui uma instância do Initial View Controller do storyboard (aquele ao lado do Segue sem código-fonte) como aRootViewController
propriedade da janela. Em seguida, torna a janela visível na tela.AppDelegate
No , substitua o método padrãoWindow
pelo seguinte código para implementar a propriedade window:public override UIWindow Window { get; set; }
Criando um Storyboard com o Xcode
Um Storyboard pode ser criado e modificado usando o Xcode para uso em seus aplicativos iOS desenvolvidos com o Visual Studio para Mac.
Os storyboards substituem totalmente os arquivos XIB individuais em seu projeto, no entanto, os controladores de exibição individuais em um Storyboard ainda podem ser instanciados usando Storyboard.InstantiateViewController
.
Às vezes, os aplicativos têm requisitos especiais que não podem ser tratados com as transições de storyboard internas fornecidas pelo Designer. Por exemplo, se você criar um aplicativo que inicia telas diferentes a partir do mesmo botão, dependendo do estado atual de um aplicativo, talvez queira instanciar os controladores de exibição manualmente e programar a transição por conta própria.
A captura de tela a seguir mostra dois controladores de exibição na superfície de design sem nenhuma sequência entre eles. A próxima seção explica como essa transição pode ser configurada no código.
Adicione um Storyboard do iPhone vazio a um projeto existente:
Clique duas vezes no arquivo Storyboard ou clique com o botão direito do mouse e selecione Abrir com > o Construtor de Interface do Xcode para abri-lo no Construtor de Interface do Xcode.
No Xcode, abra a Biblioteca (por meio de Exibir > Mostrar Biblioteca ou Shift + Command + L) para mostrar uma lista de objetos que podem ser adicionados ao Storyboard. Adicione a
Navigation Controller
ao Storyboard arrastando o objeto da lista para o Storyboard. Por padrão, oNavigation Controller
fornecerá duas telas. A tela à direita é umaTableViewController
que você substituirá por uma visualização mais simples para que possa ser removida clicando na visualização e pressionando a tecla Delete.Esse controlador de exibição terá sua própria classe personalizada e também precisará de sua própria ID de Storyboard. Quando você clica na caixa acima dessa exibição recém-adicionada, há três ícones, o mais à esquerda dos quais representa o controlador de exibição da exibição. Ao selecionar esse ícone, você pode definir os valores de classe e ID na guia de identidade do painel direito. Defina esses valores para
MainViewController
e certifique-se de verificarUse Storyboard ID
.Usando a Biblioteca novamente, arraste um controle Controlador de Exibição para a tela. Isso será definido como o controlador de exibição raiz. Segurando a tecla Control , clique e arraste do Controlador de Navegação à esquerda para o Controlador de Exibição recém-adicionado à direita e selecione o controlador de exibição raiz no menu.
Este aplicativo navegará para outro modo de exibição, portanto, adicione mais um modo de exibição ao Storyboard, assim como antes. Chame-o
PinkViewController
de , e defina esses valores da mesma maneira que com oMainViewController
.Como o controlador de exibição terá um plano de fundo rosa, defina essa propriedade no painel de atributos usando a lista suspensa ao lado de
Background
.Como queremos
MainViewController
navegar até oPinkViewController
, o primeiro precisará de um botão para interagir. Use a Biblioteca para adicionar um botão aoMainViewController
.
O storyboard está completo, mas se você implantar o projeto agora, verá uma tela em branco. Isso ocorre porque você ainda precisa dizer ao IDE para usar o storyboard e configurar um controlador de exibição raiz para servir como a primeira exibição. Normalmente, isso pode ser feito por meio de Opções de Projeto, conforme mostrado anteriormente. No entanto, neste exemplo, adicionaremos o seguinte código ao AppDelegate para obter o mesmo resultado:
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public static UIStoryboard Storyboard = UIStoryboard.FromName ("MainStoryboard", null);
public static UIViewController initialViewController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
initialViewController = Storyboard.InstantiateInitialViewController () as UIViewController;
window.RootViewController = initialViewController;
window.AddSubview(initialViewController.View);
window.MakeKeyAndVisible ();
return true;
}
}
Isso é muito código, mas apenas algumas linhas não são familiares. Primeiro, você registra o storyboard com o AppDelegate passando o nome do storyboard, MainStoryboard. Em seguida, você informa ao aplicativo para instanciar um controlador de exibição inicial do storyboard chamando InstantiateInitialViewController
o storyboard e define esse controlador de exibição como o controlador de exibição raiz do aplicativo. Esse método determina a primeira tela que o usuário vê e cria uma nova instância desse Controlador de Exibição.
Observe no painel de solução que o IDE criou uma MainViewcontroller.cs
classe e seu arquivo correspondente *.designer.cs
quando você adicionou o nome da classe ao Painel de propriedades na etapa 4. Essa classe criou um construtor especial que inclui uma classe base:
public MainViewController (IntPtr handle) : base (handle)
{
}
Ao criar um Storyboard usando o Xcode, o IDE adicionará automaticamente o atributo [Register] na parte superior da *.designer.cs
classe e passará um identificador de cadeia de caracteres, que é idêntico ao ID do Storyboard especificado na etapa anterior. Isso vinculará o C# à cena relevante no Storyboard.
[Register ("MainViewController")]
public partial class MainViewController : UIViewController
{
public MainViewController (IntPtr handle) : base (handle)
{
}
//...
}
Para obter mais informações sobre como registrar classes e métodos, consulte Tipo Registrar.
A última etapa desta classe é conectar o botão e a transição para o controlador de exibição rosa. Você instanciará o PinkViewController
do Storyboard; em seguida, você programará uma sequência de push com PushViewController
, conforme ilustrado pelo código de exemplo a seguir:
public partial class MainViewController : UIViewController
{
UIViewController pinkViewController;
public MainViewController (IntPtr handle) : base (handle)
{
}
public override void AwakeFromNib ()
{
// Called when loaded from xib or storyboard.
this.Initialize ();
}
public void Initialize()
{
//Instantiating View Controller with Storyboard ID 'PinkViewController'
pinkViewController = Storyboard.InstantiateViewController ("PinkViewController") as PinkViewController;
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
//When we push the button, we will push the pinkViewController onto our current Navigation Stack
PinkButton.TouchUpInside += (o, e) =>
{
this.NavigationController.PushViewController (pinkViewController, true);
};
}
}
A execução do aplicativo produz um aplicativo de 2 telas:
Segues condicionais
Muitas vezes, passar de um controlador de exibição para o próximo depende de uma determinada condição. Por exemplo, se estivéssemos fazendo uma tela de login simples, só gostaríamos de passar para a próxima tela se o nome de usuário e a senha tivessem sido verificados.
No próximo exemplo, adicionaremos um campo de senha ao exemplo anterior. O usuário só poderá acessar o PinkViewController se digitar a senha correta, caso contrário, um erro será exibido.
Antes de começarmos, siga as etapas anteriores de 1 a 8. Nessas etapas, criamos nosso storyboard, começamos a criar nossa interface do usuário e informamos ao nosso Delegado de Aplicativo qual controlador de exibição usar como seu RootViewController.
Agora, vamos criar nossa interface do usuário e adicionar as exibições adicionais listadas ao
MainViewController
para torná-lo parecido com o da captura de tela a seguir:- Campo de interface do usuário
- Nome: PasswordTextField
- Espaço reservado: 'Digite a senha secreta'
- UILabel
- Texto: 'Erro: senha errada. Você não passará!'
- Color: vermelha
- Alinhamento: centro
- Linhas: 2
- Caixa de seleção 'Oculto' marcada
- Campo de interface do usuário
Crie um Segue entre o botão Ir para Rosa e o controlador de exibição arrastando com a tecla Control pressionada do PinkButton para o PinkViewController e, em seguida, selecionando Push on mouse-up.
Clique no Segue e dê a ele o Identificador
SegueToPink
:Por fim, adicione o seguinte
ShouldPerformSegue
método àMainViewController
classe:public override bool ShouldPerformSegue (string segueIdentifier, NSObject sender) { if(segueIdentifier == "SegueToPink"){ if (PasswordTextField.Text == "password") { PasswordTextField.ResignFirstResponder (); return true; } else{ ErrorLabel.Hidden = false; return false; } } return base.ShouldPerformSegue (segueIdentifier, sender); }
Neste código, combinamos o segueIdentifier com o nosso SegueToPink
segue, para que possamos testar uma condição; neste caso, uma senha válida. Se nossa condição retornar true
, o Segue executará e apresentará o PinkViewController
. Se false
, o novo controlador de exibição não será apresentado.
Podemos aplicar essa abordagem a qualquer Segue neste controlador de exibição verificando o argumento segueIdentifier para o método ShouldPerformSegue. Neste caso, temos apenas um identificador Segue – SegueToPink
.
Resumo
Este artigo apresenta o conceito de Storyboards e como eles podem ser benéficos no desenvolvimento de aplicativos iOS. Ele discute cenas, controladores de exibição, exibições e hierarquias de exibição e como as cenas são vinculadas a diferentes tipos de Segues. Ele também explora a instanciação de controladores de exibição manualmente a partir de um storyboard e a criação de Segues condicionais.