змінити розмір суперперегляду після того, як підпрограми динамічно змінюються за допомогою авторозкладки


83

Я не можу заради любові до бога повісити цю зміну розміру нагляду.

У мене є UIView *superview з 4 UILabels. 2 функція як заголовок для 2 інших.

Вміст у всіх 4 динамічно надходить із бази даних.

SizeToFitvs SizeThatFits:(CGSize)проти UIView systemLayoutSizeFittingSize:, проходячи UILayoutFittingCompressedSizeабо UILayoutFittingExpandedSize.

Я програмно використовую авторозкладку і встановив висоту суперперегляду рівною чи більшою фіктивному числу.

де і як я використовую ці SizeToFitvs sizeThatFits:(CGSize)vs UIView systemLayoutSizeFittingSize:, передаючи UILayoutFittingCompressedSizeабо UILayoutFittingExpandedSize. Я прочитав тут багато порад щодо стека, але в підсумку ні з чим.

ЧИ мені потрібно перераховувати обмеження для суперпрегляду десь конкретно. Мейбі встановив висоту як «властивість» у своєму класі контролера та видалив та прочитав її? Банкомат Я намагався розмістити все скрізь, а потім і дещо. Тим не менше, я отримую однаковий кінцевий результат із висотою фіктивного тексту та текстом, що плаває назовні. Навіть після встановлення clipsToBound для підпрогляду.

Я дряпаю волосся .. допомога


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

Відповіді:


104

Якщо ви використовуєте автоматичне розміщення, ось що вам потрібно зробити:

  1. Переконайтеся, що ви не додаєте обмежень фіксованої ширини та / або висоти до жодного з своїх підпоглядів (залежно від того, які розміри (розміри) ви хочете динамічно розмірювати). Ідея полягає у тому, щоб дозволити внутрішньому розміру вмісту кожного підпрогляду визначати висоту підпрогляду. UILabels поставляються з 4 автоматичними неявними обмеженнями, які намагатимуться (з меншим за Пріоритетом пріоритетом) утримувати рамку етикетки в точному розмірі, необхідному для розміщення всього тексту всередині.

  2. Переконайтеся, що краї кожної наклейки жорстко з’єднані (з необхідними обмеженнями пріоритету) до країв один одного та їх супервигляду. Ви хочете переконатись, що якщо ви уявляєте, що одна з етикеток збільшується в розмірі, це змусить інші етикетки звільнити місце для неї, а головне змусить суперпогляд також розширитися.

  3. Додайте обмеження до суперперегляду лише для того, щоб встановити його положення, а не розмір (принаймні, не для розміру (-ів), який потрібно динамічно розмірювати). Пам'ятайте, що якщо ви правильно встановите внутрішні обмеження, його розмір буде визначатися розмірами всіх підпрограм, оскільки його краї якимось чином пов'язані з їхніми.

Це воно. Вам не потрібно телефонувати sizeToFitабо systemLayoutSizeFittingSize:змусити це працювати, просто завантажте свої погляди та встановіть текст, і це повинно бути все. Механізм компонування системи зробить обчислення для вирішення ваших обмежень. (Якщо що-небудь, можливо, вам доведеться зателефонувати setNeedsLayoutдо супервізу ... але це не потрібно.)


Спасибі смайлиборг. Пізня відповідь, оскільки я був у середині проекту і не цілком зрозумів те, що ти надумав. Тепер у мене була можливість попрацювати ще з обмеженнями в програмному і особливо з, constraintsWithVisualFormatі я повністю розумію вашу думку щодо розтягування підпоглядів, що розтягуються, і якось виштовхує суперпрегляд до його розміру :) Ще раз спасибі
Педроінпіс,

Я згоден з рішенням, але воно не працює для мене, перевірте stackoverflow.com/questions/34635838/…
Омер,

Ця відповідь - магія. Набагато менше зусиль з мого боку, щоб вигляди виглядали добре.
Кріс,

1
Слід зазначити, що ви повинні встановити, translatesAutoresizingMaskIntoConstraints = NOякщо ви використовуєте xib.
KudoCC

translatesAutoresizingMaskIntoConstraints = НІ - це відповідь для мого випадку. Але тепер вигляд контейнера втратив кадр і його походження завжди (0,0), я не можу помістити його туди, куди я хочу. stackoverflow.com/questions/45548372/…
karim

24

Використовуйте подання контейнера

У наступному прикладі я маю зображення розміром 30x30, і UILabelвоно менше, ніж вміст подання з текстом-заповнювачем. Мені потрібно, щоб вміщуючий вигляд був принаймні таким же великим, як і зображення, але він повинен був зростати, щоб містити багаторядковий текст.

У візуальному форматі внутрішній контейнер виглядає так:

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|

Потім встановіть вигляд, що містить, так, щоб він відповідав висоті мітки. Тепер вигляд, що містить, буде мати розмір мітки.

Як зазначив у своїй відповіді @smileyborg, жорстке підключення вмісту до суперперегляду повідомляє механізму компонування, що простий вигляд контейнера повинен сприяти його зростанню.

Жовті прямокутники вирівнювання

Якщо ви хочете, щоб прямокутники жовтого вирівнювання були додані -UIViewShowAlignmentRects YESдо списку запущених аргументів вашої схеми.

UILabel, що є багаторядковою


12
-UIViewShowAlignmentRects YES- чудова порада!
Ральфонсо,

2
У цьому випадку контейнер повинен лише адаптувати свою висоту до етикетки. Що робити, якщо контейнер повинен адаптуватися до суми висот більш ніж одного виду?
da Rocha Pires

7

Це було значно полегшено завдяки введенню Stack Views в iOS 9. Використовуйте подання стека всередині вашого подання, щоб містити весь вміст, який змінюється, а потім просто зателефонувати

view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()

після зміни вмісту. Тоді ви можете отримати свій новий розмір, зателефонувавши

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

якщо вам коли-небудь потрібно буде розрахувати точний розмір, необхідний для перегляду.


2
Я використовую StackView і додаю подання динамічно, ці погляди не змінюються. @ JacobRuth
Mansuu ....

6

Це майже відповідає відповіді @smileyborg і містить конкретний приклад.

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

Не буде описувати всіх обмежень, але тих, що стосуються обчислення висоти об'єктів інтерфейсу.

  1. [Етикетка] Мітки не повинні мати фіксованого heightобмеження, у цьому випадку AutoLayout не змінить розмір ярликів відповідно до тексту, тому встановлення обмежень краю є ключовим. (зелені стрілки)
  2. [Subview] Крок 1 і 3 дуже легко виконувати, але цей крок може бути неправильно зрозумілий. Як і у випадку з мітками, підпрограми не повинні мати heightвстановлених обмежень. Усі підпрограми повинні мати topнабір обмежень, ігноруючи bottomобмеження, що може змусити вас думати, що спричинить незадоволене виняток обмеження під час виконання, але це не станеться, якщо ви встановите bottomобмеження для останнього підпрогляду. Якщо цього не зробити, макет буде підірвано. (червоні стрілки)

  3. [Superview] Встановіть усі обмеження так, як вам потрібно, але приділіть велику увагу heightобмеженню. Призначте йому випадкове значення, але зробіть це необов’язковим, AutoLayout встановить висоту точно, щоб відповідати підпроглядам. (сині стрілки)

Це чудово працює, немає необхідності викликати будь-які додаткові методи оновлення системного макета.


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