Automatyczne układanie kakao: przytulanie treści a priorytet odporności na kompresję treści


643

Nie mogę znaleźć jednoznacznej odpowiedzi w dokumentacji Apple dotyczącej autoukładu Cocoa o różnicy między przytulaniem treści a odpornością na kompresję.

Czy ktoś może wyjaśnić ich zwyczaje i różnice?


49
Jednym z głównych zagadek życia jest to, dlaczego nie nazwali tego po prostu „Odpornością na ekspansję”. Te dwie cechy to nic innego jak „odporność na rozszerzanie się” i „odporność na ściskanie” . Termin „przytulanie” jest szalony.
— Fattie

3
Jeśli masz za dużo miejsca, to content-hugging: walczyłby z pustą przestrzenią. Zmusiłoby to widok do obejścia ciebie. Ale jeśli nie masz za dużo miejsca, a zamiast tego masz bardzo mało miejsca, wówczas content-compressions-resistancewalczyłbyś z twoim widokiem, ponieważ nie był w stanie wyświetlić całej jego zawartości, np. Etykiety zostałyby obcięte.
— Honey

Odpowiedzi:


1319

Szybkie podsumowanie pojęć:

  • Przytulanie => treść nie chce się rozwijać
  • Odporność na ściskanie => zawartość nie chce się kurczyć

Przykład:

Powiedz, że masz taki przycisk:

[       Click Me      ]

i przypiąłeś krawędzie do większego podglądu z priorytetem 500.

Następnie, jeśli Priorytet przytulania> 500 będzie wyglądał następująco:

[Click Me]

Jeśli priorytet przytulania <500 będzie wyglądał następująco:

[       Click Me      ]

Jeśli superwizja teraz się zmniejszy, to jeśli priorytet Odporności na ściskanie> 500, będzie to wyglądać tak

[Click Me]

W przeciwnym razie, jeśli priorytet odporności na ściskanie wynosi <500, może wyglądać następująco:

[Cli..]

Jeśli to nie działa tak, prawdopodobnie masz jakieś inne ograniczenia, które psują twoją dobrą pracę!

Np. Możesz przypiąć go do superwizji z priorytetem 1000. Lub możesz mieć priorytet szerokości. Jeśli tak, może to być pomocne:

Edytor> Dopasuj rozmiar do treści


37
Co jeśli priorytet obejmuje przytulanie == 500?
— bradley.ayers

1
Chciałbym założyć, (ale to nie jest zwykle dobrym pomysłem) by go traktować jako> 500 jak typowe zachowania zaokrąglania. Jednak tego nie testowałem.
— Joshua Nozzi

najprawdopodobniej
— pojawi się

8
@ bradley.ayers Do komentarza MaxDesyatova stanie się to tylko wtedy, gdy będziesz mieć sprzeczne ograniczenia o wymaganym priorytecie (1000). W przypadku konfliktu dwóch ograniczeń o niższym priorytecie rozwiązanie jest niejednoznaczne, więc silnik Auto Layout wybierze tylko jedno prawidłowe rozwiązanie i właśnie to zobaczysz (bez ostrzeżeń). Oczywiście nie jest to dobre, ponieważ teraz to od wewnętrznej implementacji silnika Auto Layout zależy, jak będzie wyglądać twój układ, i teoretycznie może to zmienić się z jednej wersji iOS na drugą!
— Smileyborg

Domyślnym priorytetem przytulania treści jest 250, a domyślnym poziomem odporności na kompresję 750. Po co więc używać 500?
— ZYiOS 15.04.15

292

Rzuć okiem na ten film instruktażowy na temat Autolayout , wyjaśniają go dokładnie

wprowadź opis zdjęcia tutaj


1
@fatuhoku, czy możesz sprawdzić ponownie, ten film jest bezpłatny
— onmyway133

31
Dyskusja na temat przytulania a oporu rozpoczyna się około 13:15 w filmie.
— Carl Smith,

1
@ onmyway133 jest to idealny film, ale niestety nie ma przykładu, w jaki sposób Ray go używa.
— Matrosov Alexander

@MatrosovAlexander Myślę, że bardzo praktycznym przykładem byłaby dynamiczna wysokość komórki z Autolayout fantageek.com/1468/…
— onmyway133

1
Pokazuje, jak używać oporu kompresji o 18:05
— Brent Faust

187

wprowadź opis zdjęcia tutaj

źródło: @mokagio

Rozmiar zawartości wewnętrznej - dość oczywisty, ale widoki ze zmienną zawartością są świadome, jak duża jest ich zawartość i opisują rozmiar zawartości za pomocą tej właściwości. Niektórymi oczywistymi przykładami widoków, które mają rzeczywiste rozmiary treści, są UIImageViews, UILabels, UIButtons.

Priorytet przytulania zawartości - im wyższy jest ten priorytet, tym bardziej widok jest odporny na powiększanie się niż jego rozmiar.

Priorytet odporności na kompresję treści - im wyższy jest ten priorytet, tym bardziej widok jest mniejszy niż jego rzeczywisty rozmiar.

Sprawdź tutaj, aby uzyskać więcej wyjaśnień: MAGIA AUTOMATYCZNEGO UKŁADANIA: PRIORYTETY ROZMIARU TREŚCI


Ilustracja jest ładna, ale co najmniej myląca. Najwyższy facet powinien powiedzieć: „Nie zamierzam (pozwolić MNIE) urosnąć”. Widok potomny sam określa, że ​​nie chce się rozwijać dzięki zachowaniu polegającemu na przytulaniu treści. Nie ma siły egzogennej (jak na ilustrowanych dłoniach), która powstrzymywałaby jej wzrost. To duża różnica.
— Manuel

6
Głosuję za tym tylko dlatego, że uwielbiam tę ilustrację.
— James Bucanek

3
Właśnie dlatego uwielbiam przepełnienie stosu… Opis Snowcrash plus ta ilustracja autorstwa mokagio = najlepsze wyjaśnienie tych właściwości w dowolnym miejscu (w tym własna dokumentacja Apple).
— Kal

40

Załóżmy, że masz przycisk z tekstem „Kliknij mnie”. Jaka powinna być szerokość tego przycisku?

Po pierwsze, zdecydowanie nie chcesz, aby przycisk był mniejszy niż tekst. W przeciwnym razie tekst zostałby obcięty. Jest to priorytet poziomej odporności na ściskanie.

Po drugie, nie chcesz, aby przycisk był większy niż powinien. Przycisk, który wyglądał tak, [Click Me], jest oczywiście zbyt duży. Chcesz, aby przycisk „przytulił” jego zawartość bez zbytniego dopełniania. Jest to horyzontalny poziom przytulania treści. W przypadku przycisku nie jest on tak silny, jak pozioma odporność na kompresję w poziomie.


19

Jeśli view.intrinsicContentSize.width != NSViewNoIntrinsicMetric, to układ automatyczny tworzy specjalne ograniczenie typu NSContentSizeLayoutConstraint. To ograniczenie działa jak dwa normalne ograniczenia:

  • ograniczenie wymagające view.width <= view.intrinsicContentSize.width priorytetu poziomego przytulania, oraz
  • ograniczenie wymagające view.width >= view.intrinsicContentSize.widthpriorytetu poziomej odporności na ściskanie.

W Swift, dzięki nowym kotwicom układu w iOS 9, możesz skonfigurować równoważne ograniczenia takie jak to:

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)

Podobnie jeśli view.intrinsicContentSize.height != NSViewNoIntrinsicMetric, to układ automatyczny tworzy taki, NSContentSizeLayoutConstraintktóry działa jak dwa ograniczenia na wysokości widoku. W kodzie wyglądałyby tak:

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)

Możesz zobaczyć te specjalne NSContentSizeLayoutConstraintwystąpienia (jeśli istnieją), drukując view.constraintspo uruchomieniu układu. Przykład:

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
nie powinno być: niech verticalCompression = view.heightAnchor.constraint (greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
— mc_plectrum

1
Tak, popełniłem błąd kopiowania / wklejania. Poprawiłem to. Dziękuję za informację.
— rob mayoff

15

Przytulanie zawartości i priorytety odporności na kompresję treści działają dla elementów, które mogą obliczać swój rozmiar wewnętrznie w zależności od nadchodzących treści.

Z dokumentów Apple :

wprowadź opis zdjęcia tutaj


plus 1 za zdjęcie (Y)
— Noor Ali Butt

Jestem zmieszany. Dla textView, który nie ma włączonego przewijania. Czy to oznacza, że ​​użytkownik wpisujący wewnętrzny rozmiar by się zmienił?
— Kochanie,

@Honey Myślę, że przy ustawionych prawidłowych ograniczeniach i wyłączonym przewijaniu widok tekstu powinien być w stanie określić wewnętrzną wysokość.
— dev gr

To nie odpowiedziało na moje pytanie. Masz na myśli to, że jeśli dużo piszę, więcej niż aktualny rozmiar textView ... Czy textView rozwija się automatycznie i zmienia rozmiar wewnętrzny?
— Honey,

Spróbuj sam. Nadaj tekstowi stałą szerokość, wyłącz przewijanie i sprawdź pożądane zachowanie. Więcej odpowiedzi można znaleźć na stronie stackoverflow.com/a/21287306/1526629 .
— dev gr

11

To Content hugging priorityjest jak gumka która jest umieszczona wokół widoku. Im wyższa wartość priorytetu, tym silniejsza gumka i tym bardziej chce ona przytulić się do swojej zawartości. Wartość priorytetową można sobie wyobrazić jako „siłę” gumki

I o Content Compression Resistanceto, jak bardzo widok „opiera się” zmniejszaniu Widok o wyższej wartości priorytetu odporności jest tym, który będzie odporny na kompresję.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.