View Code em iOS — Destravando conhecimento.

Eduardo Lombardi
5 min readSep 24, 2021

--

Photo by Ilya Pavlov on Unsplash

No mundo iOS podemos criar interfaces de várias maneiras. Arquivos XIB vêm lá do xcode 4 e são uma maneira visual de criar um layout, e neles contemos elementos dentro de UIViews ou UIView Controllers separadas. (Sim, podemos ter mais de uma UIView “mãe” dentro do mesmo XIB). Arquivos Storyboard surgiram depois e contêm ferramentas visuais para a criação de telas bem como a navegação e hierarquia das mesmas.

Acima vemos um exemplo de um trecho de um arquivo storyboard. Se olharmos com cuidado percebemos que ele é um XML legível que descreve todos os parâmetros visuais e configurações presentes no mesmo. O pulo do gato relativo tanto ao storyboard quanto ao XIB são os valores de identificação, como sceneID, destination, id, entre outros. Esses valores são de controle do Xcode e fica difícil saber/inferir seu valor apenas olhando para o código dos arquivos. Quando mais de uma pessoa altera o mesmo arquivo devemos resolver os conflitos na mão tomando cuidado para que o XML fique formatado corretamente e com sentido. Mas não foge muito de definir qual o valor correto a ficar no arquivo dada mais de uma alteração no mesmo lugar (uma constant de uma constraint, por exemplo).

Um problema presente nos storyboards e XIB’s atende pelo nome de IBDesignable e IBInspectable. Abrir um arquivo visual desses que contenha alguma propriedade associada com alguma dessas marcações fará com que o Xcode faça o build do projeto novamente. A cada alteração do arquivo, para que o visual represente de fato o que está sendo alterado também será realizado um novo build do projeto. Em máquinas com menor poder de processamento e RAM, isso pode se tornar custoso, dada a quantidade de softwares abertos e quantidade de builds sendo executadas em sequência.

O view code é uma maneira de criar layouts utilizando apenas código. Para compreender como ele funciona precisamos entender não somente do ciclo de vida da aplicação, como do ciclo de vida das view controllers e de qualquer elemento de interface a ser utilizado.

O elemento principal a ser estudado é a UIView, um coringa na construção de layouts utilizando viewCode. A documentação (bem extensa) está aqui . Adicionamos elementos dentro da UIView ou UIViewController com uma sintaxe como a abaixo:

Tem algumas coisas importantes à serem ditas sobre o bloco de código acima. O atributo lazy faz com que a closure seja executada somente quando uma operação de leitura for realizada na variável myLabel. Fica interessante também para deixar o seu método inicializador da view mais simples e conciso. Quando você chamar self.label a sua view já estará pronta para uso. Sempre criamos uma view utilizando o construtor que passa um frame para ela mesmo que seja .zero (x:0, y:0, width:0, height:0) e marcamos como falsa a propriedade translateAutoResizingMaskIntoConstraints. Isso faz com que a view seja criada, adicionada no ponto 0 da view e não seja criada nenhuma constraint baseada nesse ponto inicial.

Sabemos que as constraints definem como as coisas serão posicionadas na tela. Como estamos falando de construção de view via código devemos definir as constraints programaticamente, e tem alguns segredos que vão facilitar a nossa vida. Devemos concentrar a criação das constraints em um método principal (com submétodos se necessário) afim de facilitar a manutenção posterior das telas. Algo como:

Imagine que chegou um bug para você resolver e é algo referente a espaçamento de uma tela específica. Você só terá que descobrir qual é a tela, porque os espaçamentos estarão sempre no método de setupConstraints ou subjacentes. A maneira mais performática (como sugerido pela própria Apple na documentação) de configurar as constraints é dentro de um método activate, que recebe um Array das mesmas.

Aqui podemos definir quaisquer constraints necessárias, incluindo centralização, altura e largura e constantes fixas. Para ver as opções disponíveis de âncoras para sua view acesse este link.

Ainda assim, nossa view não sabe como que os elementos de interface ficam na hierarquia da mesma, então precisamos de um outro método concentrador responsável pelos addSubviews da mesma. Veja um exemplo abaixo:

Se atente ao detalhe de que este método deverá ser chamado antes do setupConstraints() para que não ocorra nenhum erro durante a execução tentando posicionar um objeto que ainda não existe na hierarquia das views.

Tem uma outra maneira de criar constraints utilizando uma Visual Formatting Language, mas confesso que ela não é muito utilizada no dia a dia e fica a seu critério utilizá-la ou não. Vou deixar aqui um tutorial do Ray WenderLitch que explica em detalhes como essa linguagem funciona, mas basicamente você escreve algo como

H:|-[icon(==iconDate)]-20-[iconLabel(120@250)]-20@750-[iconDate(>=50)]-|

e fica “visual” o posicionamento das views e suas relações.

E o swiftUI?

O swiftUI surgiu recentemente como uma nova maneira de desenvolver interfaces no mundo iOS. Veio muito em uma linha declarativa e de muito fácil compreensão, mas totalmente diferente da utilização do framework UIKit. Funciona de maneira muito parecida em toda a linha de produtos da apple, desde a construção de layouts para Apple Watch, até telas para o Mac. Opera iOS 13+ e aqui no Brasil por questões de retrocompatibilidade com versões antigas muito utilizadas ainda não despontou. Nele temos arquivos que herdam de View (e não UIView) com uma propriedade body em que configuramos todo o conteúdo necessário. Para entender mais como funciona a construção de views em swiftUI veja este artigo em que mostro o processo de construção do app abaixo.

Vou deixar aqui outra sugestões de artigos que escrevi sobre temas relacionados que considero importantes:

A fim de saber mais sobre bugs? considere ler este artigo.

Quer entender mais sobre soft skills na área? entre neste link.

Para saber como é trabalhar em uma grande empresa, leia este artigo.

Não deixe de conferir este outro aplicativo que desenvolvi utilizando swiftUI:

Se quiser dicas de apps bacanas pra instalar no seu iDevice, dá uma olhada em

Me ajude com um café

--

--