Автоматичний какао-какао: пріймання вмісту та пріоритет стійкості до стиснення вмісту


643

Я не можу знайти чіткої відповіді в документації Apple щодо Autolayout Cocoa про різницю між обіймом вмісту та стійкістю до стиснення.

Чи може хтось пояснити їх звичаї та різницю?


49
Одне з головних загадкових для життя - це те, чому вони не назвали це просто "Опір розширення". Ці дві якості - це не що інше, як "Опір розширення" та "Опір стисненню" . Термінологія "обіймати" - божевільна.
Fattie

3
Якщо у вас занадто багато місця, тоді content-hugging: будете боротися проти наявності білого простору. Це просто змусить погляд обійти вас. Але якщо у вас немає занадто багато місця, а натомість ви маєте дуже мало місця, то ви content-compressions-resistanceб боролися проти вашої точки зору від того, що не зможете показати весь його вміст, наприклад, мітки будуть врізані.
Мед

Відповіді:


1319

Короткий підсумок понять:

  • Обіймати => вміст не хоче рости
  • Опір стисненню => вміст не хоче скорочуватися

Приклад:

Скажіть, у вас є така кнопка:

[       Click Me      ]

і ви прикололи краї до більшого огляду з пріоритетом 500.

Тоді, якщо пріоритет обіймів> 500, це буде виглядати приблизно так:

[Click Me]

Якщо пріоритет обіймати <500, він виглядатиме так:

[       Click Me      ]

Якщо тепер нагляд зменшиться, якщо пріоритет стійкості до стиснення> 500, він буде виглядати приблизно так

[Click Me]

Ще, якщо пріоритет стійкості до стиснення <500, це може виглядати так:

[Cli..]

Якщо це не працює так, то, напевно, у вас виникають інші обмеження, які псують вашу добру роботу!

Наприклад, ви могли б прикріпити його до перегляду з пріоритетом 1000. Або у вас може бути пріоритет ширини. Якщо це так, це може бути корисно:

Редактор> Розмір для вмісту


37
Що робити, якщо пріоритет обіймати == 500?
bradley.ayers

1
Я б припустив (але це, як правило, не дуже гарна ідея), це трактується як> 500, як типова поведінка округлення. Це ще не перевірено.
Джошуа Ноцзі

швидше за все, ви отримаєте попередження "Неможливо одночасно задовольнити обмеження"
Макс Десятов

8
@ bradley.ayers На коментар MaxDesyatov, це відбудеться лише в тому випадку, якщо у вас є суперечливі обмеження з обов'язковим пріоритетом (1000). Якщо два обмеження з нижчим пріоритетом конфліктують, рішення є неоднозначним, тому двигун автоматичної компонування просто вибере одне дійсне рішення, і це те, що ви побачите (без попереджень). Очевидно, це не добре, тому що тепер залежить від внутрішньої реалізації двигуна Auto Layout, щоб вибрати, як виглядає ваш макет, і теоретично це може змінитися від однієї версії iOS до наступної!
смайликборг

За замовчуванням пріоритет обняття вмісту становить 250, а типовий опір стиснення вмісту - 750. Тож навіщо використовувати 500?
ZYiOS

292

Подивіться цей відеоурок про Autolayout , вони ретельно пояснюють це

введіть тут опис зображення


1
@fatuhoku Ви можете перевірити ще раз, це відео безкоштовно
onmyway133

31
Обговорення проти опору починається приблизно в 13:15 на відео.
Карл Сміт

1
@ onmyway133 це ідеальне відео, але, на жаль, немає прикладу того, як Рей це використовує.
Матросов Олександр

@MatrosovAlexander Я думаю, що дуже практичним прикладом може бути динамічна висота комірок з Autolayout fantageek.com/1468/…
onmyway133

1
Він показує, як використовувати опір стисненню о 18:05
Brent Faust

187

введіть тут опис зображення

джерело: @mokagio

Внутрішній розмір вмісту - досить зрозумілий, але перегляди зі змінним вмістом усвідомлюють, наскільки великий їхній вміст, і описують розмір їх вмісту завдяки цій властивості. Деякі очевидні приклади поглядів, які мають внутрішній розмір вмісту, - це UIImageViews, UILabels, UIButtons.

Пріоритет обіймання вмісту - чим вищий цей пріоритет, тим більше опір чинить опір, що зростає більше, ніж його внутрішній розмір вмісту.

Пріоритет стійкості до стиснення вмісту - Чим більший цей пріоритет, тим більше огляд чинить опір зменшенню менше, ніж його внутрішній розмір вмісту.

Ознайомтесь тут, щоб отримати додаткові пояснення: АВТОМАТИЧНА МАГІЯ: ЗМІСТ РОЗМІРНИХ ПРИОРИТЕТІВ


Ілюстрація приємна, але, як мінімум, оманлива. Топ-хлопець повинен сказати "Я не збираюся (нехай МЕ) рости". Дитячий погляд самостійно визначає, що він не хоче рости через його контент-обіймаючу поведінку. Не існує жодної екзогенної сили (як на зображених руках), яка б не зупинила її зростання. Це велика різниця.
Мануель

6
Я голосую за це лише тому, що люблю ілюстрації.
Джеймс Буканек

3
Ось чому я люблю Stack Overflow… Опис Snowcrash плюс ця ілюстрація mokagio = найкраще пояснення цих властивостей де завгодно (включаючи власну документацію Apple).
Кал

40

Скажімо, у вас є кнопка з текстом "Клацніть на мене". Якої ширини має бути ця кнопка?

По-перше, ви точно не хочете, щоб кнопка була меншою, ніж текст. Інакше текст буде вирізаний. Це пріоритет горизонтального опору на стиск.

По-друге, ви не хочете, щоб кнопка була більшою, ніж повинна бути. Кнопка, яка виглядала так, [Клікніть мене], очевидно, занадто велика. Ви хочете, щоб кнопка "обійняла" її вміст, не надто сильно затуляючи. Це горизонтальний пріоритет змісту. Для кнопки вона не така сильна, як пріоритет горизонтального опору стисненню.


19

Якщо view.intrinsicContentSize.width != NSViewNoIntrinsicMetric, то автоматичне розташування створює особливе обмеження типу NSContentSizeLayoutConstraint. Це обмеження діє як два нормальних обмеження:

  • обмеження, що вимагає view.width <= view.intrinsicContentSize.widthпріоритет горизонтального обіймання, і
  • обмеження, що вимагає view.width >= view.intrinsicContentSize.widthпріоритету горизонтального опору стиснення.

У Swift, за допомогою нових якорів компоновки iOS 9, ви можете встановити такі еквівалентні обмеження:

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)

Аналогічно, якщо view.intrinsicContentSize.height != NSViewNoIntrinsicMetric, тоді автоматичний макет створює функцію, NSContentSizeLayoutConstraintяка діє як два обмеження на висоту подання. У коді вони виглядатимуть так:

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)

Ви можете побачити ці спеціальні NSContentSizeLayoutConstraintекземпляри (якщо вони існують), надрукувавши view.constraintsпісля запуску макета. Приклад:

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
чи не так: нехай вертикальний компресія = view.heightAnchor.constraint (більшийThanOrEqualToConstant: view.intrinsicContentSize.height)
mc_plectrum

1
Так, я зробив помилку копіювання / вставки. Я це виправив. Дякую, що повідомили.
грабувати майофф

15

Пріоритети стійкості обіймів та стиснення вмісту працюють для елементів, які можуть обчислювати їх розмір внутрішньо залежно від вмісту, який надходить.

З документів Apple :

введіть тут опис зображення


плюс1 для зображення (Y)
Нур Алі Батт

Я збентежений. Для textView, у якому не включена прокрутка. Чи означає це, що на кожного користувача, який вводить внутрішній розмір, зміниться?
Мед

@Honey Я думаю, що при правильних встановлених обмеженнях та прокрутці вимкнено, перегляд тексту повинен мати можливість визначати внутрішню висоту.
dev gr

Це не відповіло на моє запитання. Ви маєте на увазі, якщо я набираю багато, більше, ніж поточний розмір textView .... чи розширюється textView автоматично і змінюється внутрішній розмір?
Мед

Спробуйте самі. Надайте перегляду тексту фіксовану ширину та відключіть прокрутку та перевірте бажану поведінку. Щоб отримати додаткові відповіді, зверніться до stackoverflow.com/a/21287306/1526629 .
dev gr

11

Це Content hugging priorityяк гумка яка розміщена навколо виду. Чим вище значення пріоритету, тим міцніше гумка і тим більше вона хоче обійняти її розмір вмісту. Значення пріоритету можна уявити як "міцність" гумки

І Content Compression Resistanceсправа полягає в тому, наскільки перегляд "чинить опір", зменшуючись . Вид з більшим значенням пріоритету опору - це той, який буде протистояти стисненню.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.