Autolayout de cacau: aceitação de conteúdo versus prioridade de resistência à compactação de conteúdo


643

Não consigo encontrar uma resposta clara na documentação da Apple sobre o Autolayout de cacau sobre a diferença entre abraços de conteúdo e resistência à compressão.

Alguém pode explicar seus usos e diferenças?


49
Um dos maiores mistérios da vida é o motivo pelo qual não o chamaram simplesmente "Resistência à Expansão". As duas qualidades nada mais são do que "Resistência à expansão" e "Resistência à compressão" . A terminologia do "abraço" é insana.
Fattie

3
Se você tem muito espaço, então content-hugging: lutaria contra ter espaço em branco. Isso apenas forçaria a vista a contornar você. Mas se você não tiver muito espaço e, em vez disso, tiver muito pouco espaço, content-compressions-resistancelutará contra sua visão por não ser capaz de mostrar todo o seu conteúdo, por exemplo, os rótulos seriam truncados.
Mel

Respostas:


1319

Um rápido resumo dos conceitos:

  • Abraçar => o conteúdo não quer crescer
  • Resistência à compressão => o conteúdo não deseja encolher

Exemplo:

Digamos que você tenha um botão como este:

[       Click Me      ]

e você fixou as bordas em uma super visão maior com prioridade 500.

Então, se Abraçar a prioridade> 500, ficará assim:

[Click Me]

Se Abraçar a prioridade <500, ficará assim:

[       Click Me      ]

Se a superview diminuir agora, se a prioridade da Resistência à compressão for maior que 500, será semelhante a

[Click Me]

Caso contrário, se a prioridade da Resistência à compressão for <500, pode ser assim:

[Cli..]

Se não funcionar assim, você provavelmente terá outras restrições que estão atrapalhando o seu bom trabalho!

Por exemplo, você pode tê-lo fixado à superview com prioridade 1000. Ou você pode ter uma prioridade de largura. Nesse caso, isso pode ser útil:

Editor> Tamanho para ajustar ao conteúdo


37
E se abraçar a prioridade == 500?
Bradley.ayers

1
Eu diria que (mas isso geralmente não é uma boa ideia) seria tratado como> 500 como um comportamento típico de arredondamento. Ainda não testei isso.
Joshua Nozzi 02/02

provavelmente você receberá o aviso "Não é possível satisfazer simultaneamente as restrições" em tempo de execução
Max Desiatov

8
@ bradley.ayers Para o comentário de MaxDesyatov, isso só acontecerá se você tiver restrições conflitantes com a prioridade necessária (1000). Se duas restrições de prioridade mais baixa entrarem em conflito, a solução é ambígua, portanto o mecanismo de Layout automático escolherá apenas uma solução válida e é isso que você verá (sem avisos). Obviamente, isso não é bom, porque agora cabe à implementação interna do mecanismo de Layout automático escolher a aparência do layout e, teoricamente, isso pode mudar de uma versão do iOS para a seguinte!
smileyborg

O conteúdo que prioriza o padrão de prioridade é 250 e o padrão de resistência à compactação de conteúdo é 750. Então, por que usar 500?
ZYiOS 15/04

292

Dê uma olhada neste vídeo tutorial sobre o Autolayout , explicado com cuidado

insira a descrição da imagem aqui


1
@fatuhoku você pode verificar novamente, este vídeo é livre
onmyway133

31
A discussão sobre abraços x resistência começa no ponto 13:15 do vídeo.
Carl Smith

1
@ onmyway133 este é um vídeo perfeito, mas infelizmente não há exemplo de como Ray o usa.
Matrosov Alexander

@MatrosovAlexander Acho que um exemplo muito prático seria a altura dinâmica das células com o Autolayout fantageek.com/1468/…
onmyway133

1
Ele mostra como usar a resistência de compressão às 18:05
Brent Faust

187

insira a descrição da imagem aqui

fonte: @mokagio

Tamanho do conteúdo intrínseco - bastante auto-explicativo, mas as visualizações com conteúdo variável estão cientes do tamanho do conteúdo e descrevem o tamanho do conteúdo por meio dessa propriedade. Alguns exemplos óbvios de visualizações com tamanhos de conteúdo intrínsecos são UIImageViews, UILabels, UIButtons.

Prioridade de abraço de conteúdo - Quanto maior for essa prioridade, mais uma visualização resiste a crescer maior que o tamanho de seu conteúdo intrínseco.

Prioridade da resistência à compactação de conteúdo - Quanto maior essa prioridade, mais uma visualização resiste a encolher menor que seu tamanho de conteúdo intrínseco.

Verifique aqui para obter mais explicações: MAGIC DE LAYOUT AUTOMÁTICO: PRIORIDADES DE TAMANHO DE CONTEÚDO


A ilustração é boa, mas enganosa, para dizer o mínimo. O cara top deve dizer "Eu não vou (ME) crescer". A visão filho define por si própria que não deseja crescer através de seu comportamento de abraço de conteúdo. Não há força exogênica (como as mãos ilustradas) que o impede de crescer. Isso é uma grande diferença.
Manuel

6
Estou votando nisso apenas porque adoro a ilustração.
precisa saber é o seguinte

3
É por isso que eu amo Stack Overflow ... A descrição do Snowcrash mais esta ilustração de mokagio = melhor explicação dessas propriedades em qualquer lugar (incluindo a documentação da Apple).
Kal

40

Digamos que você tenha um botão com o texto "Clique em mim". Qual a largura desse botão?

Primeiro, você definitivamente não deseja que o botão seja menor que o texto. Caso contrário, o texto seria cortado. Essa é a prioridade da resistência à compressão horizontal.

Segundo, você não deseja que o botão seja maior do que precisa. Um botão que se parece com isso, [Click Me], é obviamente muito grande. Você deseja que o botão "abraça" seu conteúdo sem muito preenchimento. Este é o conteúdo horizontal que abraça a prioridade. Para um botão, ele não é tão forte quanto a prioridade da resistência à compressão horizontal.


19

Se view.intrinsicContentSize.width != NSViewNoIntrinsicMetric, o layout automático cria uma restrição especial de tipo NSContentSizeLayoutConstraint. Essa restrição atua como duas restrições normais:

  • uma restrição que exige view.width <= view.intrinsicContentSize.widthcom a prioridade de abraço horizontal, e
  • uma restrição que exige view.width >= view.intrinsicContentSize.widthcom a prioridade da resistência à compressão horizontal.

No Swift, com as novas âncoras de layout do iOS 9, você pode configurar restrições equivalentes como esta:

let horizontalHugging = view.widthAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalHugging.priority = view.contentHuggingPriority(for: .horizontal)

let horizontalCompression = view.widthAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalCompression.priority = view.contentCompressionResistancePriority(for: .horizontal)

Da mesma forma, se view.intrinsicContentSize.height != NSViewNoIntrinsicMetric, o layout automático cria um NSContentSizeLayoutConstraintque age como duas restrições na altura da vista. No código, eles ficariam assim:

let verticalHugging = view.heightAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalHugging.priority = view.contentHuggingPriority(for: .vertical)

let verticalCompression = view.heightAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalCompression.priority = view.contentCompressionResistancePriority(for: .vertical)

Você pode ver essas NSContentSizeLayoutConstraintinstâncias especiais (se elas existirem) imprimindo view.constraintsapós a execução do layout. Exemplo:

label.constraints.forEach { print($0) }

// Output:
<NSContentSizeLayoutConstraint:0x7fd82982af90 H:[UILabel:0x7fd82980e5e0'Hello'(39)] Hug:250 CompressionResistance:750>
<NSContentSizeLayoutConstraint:0x7fd82982b4f0 V:[UILabel:0x7fd82980e5e0'Hello'(21)] Hug:250 CompressionResistance:750>

1
que não deveria ser: vamos verticalCompression = view.heightAnchor.constraint (greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
mc_plectrum

1
Sim, cometi um erro de copiar / colar. Eu o corrigi. Obrigado por me avisar.
Rob mayoff

15

As prioridades de resistência a compactação e resistência à compactação de conteúdo funcionam para elementos que podem calcular seu tamanho intrinsecamente, dependendo do conteúdo que está chegando.

Dos documentos da Apple :

insira a descrição da imagem aqui


mais1 para a imagem (Y)
Noor Ali Butt

Estou confuso. Para um textView que não tem a rolagem ativada. Isso significa que por usuário digitando o tamanho intrínseco mudaria?
Honey

@ Mel Eu acho que, com as restrições corretas definidas e a rolagem desativada, a exibição de texto deve ser capaz de dizer a altura intrínseca.
dev gr

Isso não respondeu à minha pergunta. Quer dizer, se eu digitar muito, mais do que o tamanho atual do textView ... o textView se expande automaticamente e altera o tamanho intrínseco?
Mel

Tente você mesmo. Dê ao textview uma largura fixa, desative a rolagem e verifique o comportamento desejado. Consulte stackoverflow.com/a/21287306/1526629 para obter mais respostas.
dev gr

11

O Content hugging priorityé como uma faixa de borracha que é colocada em torno de uma vista. Quanto mais alto o valor da prioridade, mais forte a faixa de borracha e mais ela deseja abraçar o tamanho do conteúdo. O valor da prioridade pode ser imaginado como a "força" do elástico

E isso Content Compression Resistanceé, o quanto uma visualização "resiste" ficando menor A Visualização com maior valor de prioridade de resistência é aquela que resistirá à compactação.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.