Pensando de maneira não ambígua para Auto Layout
Na jornada para tornar-me um desenvolvedor iOS, tive que reviver e encarar todos aqueles temores que adquiri quando estava mexendo com CSS para criar um site para os meus pais. Durante esse período, meus esforços para criar o layout desejado, foram repetidamente frustrados, me deixando com uma vaga sensação de que muito do que estava relacionado a layout era um grande processo de tentativa e erro.
Em um projeto recente, tive que implementar Auto Layout em um app para iOS, mas dessa vez, tentei começar do início. Fiz questão de buscar entender os porquês do comportamento das constraints e o que torna um layout funcional, sem contraints desnecessárias. Para minha surpresa, trabalhar com Auto Layout dentro do Interface Builder do Xcode é um processo muito mais lógico do que eu esperava, e qualquer ambiguidade é claramente destacada pelo programa para que seja resolvida.
De todos os ensinamentos sobre Auto Layout, o mais importante para mim é voltar às bases e então tirar conclusões. O que exatamente o programa precisa saber para posicionar um item na tela? Ele precisa de uma coordenada x e y (posição), além de uma largura e uma altura (tamanho)… E só. Com essas poucas informações é feito o layout de uma view inteira. Repita com todas as views e temos o layout de uma página do app.
Agora, o Auto Layout é algo um pouco diferente de um layout normal, no sentido que ele se adapta conforme o formato da tela e sua orientação. Como então decidir o que deve ser fixo e o que ele deve adaptar? E como passar isso claramente ao Interface Builder?
Continuando o raciocínio das bases de layout, podemos expandir isso para o Auto Layout. Agora, além de cada view precisar de uma posição e um tamanho, ela também precisa de um, e apenas um, parâmetro que deve ser mutável. Vamos separar o problema em um problema menor e analisar. Considere somente o eixo X da seguinte view:
Vamos considerar os valores que existem no eixo X:
- Leading
- Trailing
- Width
No eixo X, essa view possui 20 de leading e 240 de width, deixando o trailing livre para se adaptar dependendo da tela, então não existe constraint para esse parâmetro. Todas as medidas envolvidas no eixo X, isto é, leading, trailing e width, foram satisfeitas. Então não existe ambiguidade quando o layout deve ser adaptado pois é claro que o trailing é o valor que deve ser modificado.
Caso ela não possuísse constraints para leading ou width, o Interface Builder destacaria um erro pois fica ambíguo qual parâmetro que é modificável. Não fica claro se a width ou o trailing deve se ajustar. Nesse caso apareceriam aquelas famosas linhas vermelhas:
Para completar o layout, faça o mesmo para o eixo Y, mas agora com os seguintes parâmetros:
- Top
- Bottom
- Height
A mesma lógica se aplica. Escolha dois desses parâmetros para serem fixos e o outro fica como adaptável. Cada uma dessas três escolhas vai ter uma influência distinta no layout do seu app, então pense nisso caso a caso.
Agora que temos uma lógica básica para a construção de layouts consistentes, podemos expandir para mais alguns parâmetros que o Interface Builder nos disponibiliza. Todos os demais parâmetros podem ser divididos nos seis nossos parâmetros inicias. Isto é, "[center] Horizontally in Container" faz com que a leading e a trailing da view sejam iguais, assim como “[center] Vertically in Container” faz o mesmo com top e bottom. Restringir "Aspect Ratio" garante que o height e a width sempre esteja na mesma proporção, e assim por diante.
Concluindo, lembre-se de dividir as constraints das suas views nos eixos X e Y, garantindo que um, e somente um, parâmetro seja deixado livre. Com isso, espero que muitos dos problemas de constraints de seus apps possam ser resolvidos, e que não haja mais ambiguidade quando se trata de Auto Layout.