Cocoa Autolayout: abbraccia il contenuto rispetto alla priorità di resistenza alla compressione del contenuto


643

Non riesco a trovare una risposta chiara sulla documentazione di Apple riguardante il cayout automatico di Cocoa sulla differenza tra abbracciare il contenuto e resistenza alla compressione.

Qualcuno può spiegare i loro usi e le differenze?


49
Uno dei maggiori misteri della vita è il motivo per cui non lo chiamavano semplicemente "Resistenza all'espansione". Le due qualità non sono altro che "Resistenza all'espansione" e "Resistenza alla compressione" . La terminologia "abbraccio" è folle.
Fattie,

3
Se hai troppo spazio, allora content-hugging: combatteresti contro lo spazio bianco. Costringerebbe semplicemente la vista a circondarti. Ma se non hai troppo spazio e invece hai pochissimo spazio, allora content-compressions-resistancecombatteresti contro la tua vista dal non poter mostrare tutto il suo contenuto, ad esempio le etichette verrebbero troncate.
Miele,

Risposte:


1319

Un breve riassunto dei concetti:

  • Hugging => content non vuole crescere
  • Resistenza alla compressione => il contenuto non vuole ridursi

Esempio:

Supponi di avere un pulsante come questo:

[       Click Me      ]

e hai appuntato i bordi a una superview più grande con priorità 500.

Quindi, se Abbraccia priorità> 500 sarà simile a questo:

[Click Me]

Se Abbraccia priorità <500 sembrerà così:

[       Click Me      ]

Se ora la superview si restringe, se la priorità di Resistenza alla compressione> 500, sarà simile a questa

[Click Me]

Altrimenti se la priorità di resistenza alla compressione <500, potrebbe apparire così:

[Cli..]

Se non funziona così, probabilmente hai altri vincoli che stanno rovinando il tuo buon lavoro!

Ad esempio, potresti averlo bloccato sulla superview con priorità 1000. Oppure potresti avere una priorità di larghezza. In tal caso, questo può essere utile:

Editor> Adatta al contenuto


37
Che cosa succede se abbraccia la priorità == 500?
Bradley.ayers,

1
Mi piacerebbe presumo (ma questo non è solitamente una buona idea) che sarebbe stato trattato come> 500 come comportamento tipico di arrotondamento. Non l'ho provato però.
Joshua Nozzi,

molto probabilmente riceverai l'avviso "Impossibile soddisfare simultaneamente i vincoli" in fase di esecuzione
Max Desiatov

8
@ bradley.ayers Al commento di MaxDesyatov, ciò avverrà solo se si hanno vincoli contrastanti con Priorità obbligatoria (1000). Se due vincoli con priorità inferiore sono in conflitto, la soluzione è ambigua, quindi il motore di layout automatico sceglierà solo una soluzione valida ed è quello che vedrai (nessun avviso). Ovviamente non va bene, perché ora dipende dall'implementazione interna del motore di layout automatico scegliere l'aspetto del layout, e teoricamente questo potrebbe cambiare da una versione iOS alla successiva!
smileyborg,

L'impostazione predefinita della priorità di abbracciamento del contenuto è 250 e l'impostazione predefinita della resistenza alla compressione del contenuto è 750. Quindi perché utilizzare 500?
ZYiOS,

292

Dai un'occhiata a questo tutorial video su Autolayout , lo spiegano attentamente

inserisci qui la descrizione dell'immagine


1
@fatuhoku puoi controllare di nuovo, questo video è gratuito
onmyway133,

31
La discussione Hugging vs. Resistance inizia all'incirca alle 13:15 del video.
Carl Smith,

1
@ onmyway133 questo è un video perfetto, ma sfortunatamente non c'è alcun esempio di come Ray lo usi.
Matrosov Alexander,

@MatrosovAlexander Penso che un esempio molto pratico sarebbe l'altezza dinamica della cella con Autolayout fantageek.com/1468/…
onmyway133

1
Mostra come usare la resistenza a compressione alle 18:05
Brent Faust,

187

inserisci qui la descrizione dell'immagine

fonte: @mokagio

Dimensioni del contenuto intrinseco : abbastanza esplicative, ma le visualizzazioni con contenuto variabile sono consapevoli di quanto sia grande il loro contenuto e descrivono la dimensione del loro contenuto attraverso questa proprietà. Alcuni esempi ovvi di visualizzazioni con dimensioni intrinseche del contenuto sono UIImageViews, UILabels, UIButtons.

Priorità di abbracciamento del contenuto : maggiore è questa priorità, più una vista resiste diventando più grande della dimensione intrinseca del contenuto.

Priorità di resistenza alla compressione del contenuto - Maggiore è questa priorità, più una vista resiste a ridursi più piccola della sua dimensione intrinseca del contenuto.

Fare clic qui per ulteriori spiegazioni: MAGIC LAYOUT AUTOMATICO: PRIORITÀ DI FORMATO DEI CONTENUTI


L'illustrazione è carina ma fuorviante per non dire altro. Il migliore dovrebbe dire "Non ho intenzione di farmi crescere". La vista figlio definisce da sola che non vuole crescere attraverso il suo comportamento di abbraccio di contenuti. Non esiste una forza esogena (come le mani illustrate) che ne impedisca la crescita. Questa è una grande differenza.
Manuel,

6
Sto votando questo solo perché amo l'illustrazione.
James Bucanek,

3
Questo è il motivo per cui amo Stack Overflow ... Descrizione di Snowcrash più questa illustrazione di mokagio = migliore spiegazione di queste proprietà ovunque (compresa la documentazione di Apple).
Kal,

40

Supponiamo che tu abbia un pulsante con il testo "Click Me". Quale larghezza dovrebbe essere quel pulsante?

Innanzitutto, sicuramente non vuoi che il pulsante sia più piccolo del testo. Altrimenti, il testo verrebbe troncato. Questa è la priorità di resistenza alla compressione orizzontale.

Secondo, non vuoi che il pulsante sia più grande di quanto deve essere. Un pulsante simile a questo, [Click Me], è ovviamente troppo grande. Volete che il pulsante "abbracci" il suo contenuto senza troppa imbottitura. Questa è la priorità di abbracciare il contenuto orizzontale. Per un pulsante, non è forte come la priorità di resistenza alla compressione orizzontale.


19

Se view.intrinsicContentSize.width != NSViewNoIntrinsicMetric, quindi il layout automatico crea un vincolo speciale di tipo NSContentSizeLayoutConstraint. Questo vincolo si comporta come due normali vincoli:

  • un vincolo che richiede view.width <= view.intrinsicContentSize.widthla priorità di abbraccio orizzontale e
  • un vincolo che richiede view.width >= view.intrinsicContentSize.widthcon la priorità di resistenza alla compressione orizzontale.

In Swift, con le nuove ancore di layout di iOS 9, è possibile impostare vincoli equivalenti come questo:

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)

Allo stesso modo, se view.intrinsicContentSize.height != NSViewNoIntrinsicMetric, il layout automatico crea un elemento NSContentSizeLayoutConstraintche agisce come due vincoli sull'altezza della vista. Nel codice, apparirebbero così:

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)

È possibile visualizzare queste NSContentSizeLayoutConstraintistanze speciali (se presenti) stampando view.constraintsdopo l'esecuzione del layout. Esempio:

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
non dovrebbe essere: let verticalCompression = view.heightAnchor.constraint (greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
mc_plectrum

1
Sì, ho fatto un errore copia / incolla. L'ho corretto. Grazie per avermi fatto sapere.
Rob Mayoff,

15

Le priorità di abbraccio e resistenza alla compressione del contenuto funzionano per elementi che possono calcolare la loro dimensione intrinsecamente a seconda del contenuto che sta arrivando.

Dai documenti Apple :

inserisci qui la descrizione dell'immagine


plus1 per l'immagine (Y)
Noor Ali Butt

Non ho capito bene. Per un textView che non ha lo scorrimento abilitato. Significa che per utente digitando la dimensione intrinseca cambierebbe?
Miele,

@Honey Penso che con i vincoli corretti impostati e lo scorrimento disabilitato, la visualizzazione del testo dovrebbe essere in grado di dire l'altezza intrinseca.
dev gr

Questo non ha risposto alla mia domanda. Vuoi dire se scrivo molto, più della dimensione corrente di textView .... textView si espande automaticamente e cambia la dimensione intrinseca?
Miele

Prova tu stesso. Assegna a textview una larghezza fissa e disabilita lo scorrimento e verifica il comportamento desiderato. Consultare stackoverflow.com/a/21287306/1526629 per ulteriori risposte.
dev gr

11

L' Content hugging priorityè come un elastico che viene posizionato intorno ad un punto di vista. Più alto è il valore di priorità, più forte è l'elastico e più vuole abbracciare alla sua dimensione del contenuto. Il valore di priorità può essere immaginato come la "forza" dell'elastico

Ed Content Compression Resistanceè, quanto una vista "resiste" diventando più piccola La vista con un valore di priorità di resistenza più elevato è quella che resisterà alla compressione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.