Tenho o seguinte código SwiftUI:
Rectangle()
.fill(Color.blue.opacity(0.5))
.frame(width: 130)
.frame(maxWidth: .infinity)
.background(Color.orange.opacity(0.5))
.padding()
.frame(maxHeight:100)
Aqui está o resultado.
Claramente pode ser visto que o retângulo interno em azul foi colocado no centro do retângulo externo. Eu tentei experimentar com o alinhamento de frames e posso ver que o alinhamento do retângulo interno só pode ser alterado alterando o alinhamento do frame do retângulo externo como segue:
.frame(maxWidth: .infinity, alignment: .trailing)
Mas nada muda se eu alterar a propriedade de alinhamento do quadro do retângulo interno.
Quero entender esse comportamento mais claramente: se a visualização é centralizada por padrão e por que a modificação do alinhamento do quadro interno não altera nada.
view
é centralizado porque o valor padrão paraalignment
o parâmetro noframe
modificador é.center
.Você pode imaginar
.frame()
que é envolver sua visualização atual com uma visualização de contêiner. Então, mudaralignment
o quadro interno não funciona porqueRectangle
não tem tamanho de conteúdo, ele apenas adapta o que vocêwidth
passa em.frame()
. Um exemplo quando a mudançaalignment
de.frame
funciona é usar withText
.Aqui,
Text("Hello")
tem seu próprio tamanho de conteúdo, quando aplicado.frame
,red border
ele apenas envolve o texto "Olá", mas não expande paragreen border
.Você pode entender mais com este excelente blog: https://fatbobman.com/en/posts/layout-dimensions-1/
A maneira como o layout funciona no SwiftUI é que as visualizações pai propõem um tamanho para seus filhos, e os filhos escolhem o tamanho que querem ter, com base na proposta. Observe que algumas visualizações podem ignorar a proposta completamente.
Da documentação , o que
frame(width:height:alignment:)
é,Podemos entender isso como propor um tamanho específico para a visualização que
frame
está modificando. Após a visualização escolher seu tamanho com base na proposta, ela é alinhada no quadro com base emalignment
. O valor padrão doalignment
parâmetro é.center
, então é por isso que as visualizações são centralizadas no quadro por padrão.A maneira como a
Rectangle
escolhe seu tamanho é que ele se redimensiona para o mesmo tamanho da proposta (todosShape
os s se comportam assim). Portanto, ele sempre cobrirá todo oframe
que você especificou. É por isso que alterar oalignment
do primeiroframe
modificador não faz nada - uma visualização que cobre todo o quadro parece a mesma, não importa como esteja alinhada dentro do quadro.O
frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:)
modificador também posiciona a visualização que está modificando em um quadro, mas ele dá a proposta de tamanho de forma diferente. Ele pega a proposta de tamanho que recebeu de seu pai e a prende aos mínimos e máximos.Então, neste caso,
.frame(maxHeight:100)
recebe a proposta de tamanho e cria um frame invisível com a largura e altura da tela de 100pt. Ele altera a altura da proposta de tamanho para 100 e a passa para baixo..padding()
recebe a proposta de tamanho e escolhe seu tamanho para ser o mesmo que o tamanho proposto. Ele reduz ainda mais a largura e a altura da proposta de tamanho por alguma quantidade de preenchimento definida pelo sistema e passa a proposta adiante..frame(maxWidth: .infinity)
recebe a proposta de tamanho e adiciona um quadro invisível do mesmo tamanho da proposta de tamanho. (O laranja.background
é adicionado a esse quadro.) Ele não altera a proposta de tamanho e a passa adiante..frame(width: 130)
recebe a proposta de tamanho e ignora a largura proposta. Ele cria um frame invisível com largura de 130pt e mesma altura que a proposta de tamanho. A largura da proposta de tamanho agora é alterada para 130pt.Rectangle
recebe a proposta de tamanho e escolhe seu tamanho como 130pt de largura.Notavelmente, o quadro adicionado por
.frame(width: 130)
é menos largo que o quadro adicionado por c.frame(maxWidth: .infinity)
, então alterar oalignment
parâmetro do quadro mais largo de.center
para.trailing
visivelmente faz a diferença.