Escrevendo View Code mais limpo usando loadView()

Compartilhe

Compartilhar no facebook
Compartilhar no google
Compartilhar no twitter
Compartilhar no linkedin

(Você também pode ler esse post no meu blog SwiftRocks. (em inglês))

A escolha entre usar Storyboards e escrever views programaticamente em um projeto iOS é muito subjetiva. Tendo lidado com ambas no passado, eu pessoalmente, apoio projetos que são completamente escritos com views programáticas – pela sua capacidade de permitir que várias pessoas façam alterações na mesma tela, sem conflitos impossíveis de se resolver, e pelo code review facilitado.

Quando alguém começa a escrever views programaticamente, um problema comum de ser enfrentado é: onde colocar o código da view. Se você seguir o padrão dos Storyboards, onde tudo relacionado às views é colocado em um ViewController, é muito fácil acabar com uma gigantesca classe “deus”:

Você pode melhorar essa situação ao mover as views para um arquivo separado e adicionar uma referência de volta ao seu ViewController, mas você ainda estará preenchendo o seu ViewController com coisas que não são necessariamente responsabilidade dele, como constraints e outras formas de setup das views – sem mencionar que agora você terá duas propriedades de view diferentes (myView e a view nativa) sem um bom motivo:

“Giant View Controllers” e ViewControllers que “sabem demais” são muito difíceis de manter e escalar. Em arquiteturas como MVVM, o View Controller deve atuar basicamente como um roteador entre a View em si e seu ViewModel; não é tarefa dele saber como desenhar as views ou como posicioná-las. Ele deve apenas repassar as informações para quem irá lidar com elas de verdade.

Para que um projeto onde as views são escritas programaticamente ser escalável, é muito importante ter uma clara separação entre os aspectos da sua arquitetura. Sua View deve ser completamente separada do seu View Controller, e felizmente existe uma maneira muito simples de sobrescrever a view original de um UIViewController, permitindo que você mantenha arquivos separados para suas views, enquanto tem a certeza de que seu ViewController não precise fazer nenhum tipo de setup nas views em si.

loadView()

loadView() é um método do UIViewController que você não vê frequentemente, mas que é muito importante para o ciclo de vida de um ViewController, por ser o responsável por fazer a propriedade view existir em primeiro lugar. Em um projeto com Storyboards, esse é o método que irá carregar seu Nib e atrelá-lo à view, mas se a tela for feita com views programáticas, tudo o que ele faz é criar uma UIView vazia. Você pode sobrescrever ele e adicionar qualquer tipo de view para a propriedade view do seu ViewController.

Note que a view é automaticamente presa às bordas do ViewController, então constraints não são necessárias para a myView externa!

Agora, view é uma referência para minha view customizada (MyView, nesse caso). Você pode construir toda a funcionalidade da sua view em um arquivo separado, sem que o ViewController tenha que saber qualquer coisa sobre ela!

Para acessar o conteúdo da MyView, você pode castar view para seu tipo customizado:

Isso parece um pouco estranho, mas se dá pelo motivo da propriedade view continuar sendo uma UIView independente do tipo que você usar. Como o tipo da view é garantido no loadView(), o force cast é completamente seguro nesse caso.

Para evitar ter que duplicar essa lógica através dos ViewControllers, os projetos da Movile definem esse comportamento dentro de um protocolo CustomView com um associated type:

O que resulta em:

Se definir o tipo de uma CustomView todas as vezes é algo que te incomodaria, você pode ir além e definir esse comportamento dentro de uma classe genérica:

Eu pessoalmente não sou fã da aproximação de usar classes genéricas, já que o compilador ainda não permite que elas possuam extensões com métodos @objc, – o que te impede de ter protocolos como UITableViewDataSource em extensões. Por outro lado, elas permitem que você não precise sobrescrever loadView(),  a não ser que algo especial precise ser feito, – o que realmente ajuda a manter seus ViewControllers limpos.

Conclusão

Sobrescrever loadView() é uma ótima maneira de fazer um projeto com views programáticas mais fáceis de ler e de se manter. Muitos projetos das empresas doo grupo Movile estão usando HasCustomView especificamente com ótimos resultados. View Coding pode não ser a sua praia, mas é algo que oferece muitas vantagens para seus projetos. Tente fazer um projeto com ele e veja o que funciona melhor para a sua realidade.

Siga-me no Twitter – @rockthebruno, e compartilhe comigo qualquer sugestão ou correção que você tiver!

Bruno Rocha

Bruno Rocha

Management of Rapiddo Marketplace's iOS team, while still developing the app myself.

Deixe um comentário

%d blogueiros gostam disto: