Я разработал свою собственную ячейку в IB, разделил ее на подклассы и соединил свои розетки с моим специальным классом. У меня есть три подпредставления в содержимом ячейки: UIView (cdView) и две метки (titleLabel и emailLabel). В зависимости от данных, доступных для каждой строки, иногда я хочу, чтобы UIView и две метки отображались в моей ячейке, а иногда только две метки. То, что я пытаюсь сделать, это установить ограничения таким образом, если я установлю свойство UIView скрытым или я удалю его из суперпредставления, две метки переместятся влево. Я попытался установить ведущее ограничение UIView на Superview (содержимое ячейки) для 10px и UILabels, ведущее ограничение на 10 px для следующего представления (UIView). Позже в моем коде
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];
if ([record.imageURL is equalToString:@""]) {
cell.cdView.hidden = YES;
}
Я скрываю свой cell.cdView и хотел бы, чтобы метки двигались влево, но они остаются в той же позиции в Cell. Я пытался удалить cell.cdView из superview, но он тоже не работал. Я приложил изображение, чтобы уточнить, о чем я.
Я знаю, как сделать это программно, и я не ищу это решение. Я хочу установить ограничения в IB, и я ожидаю, что мои подпредставления будут перемещаться динамически, если другие виды будут удалены или скрыты. Можно ли это сделать в IB с автопрокатом?
.....
Ответы:
Это возможно, но вам придется проделать небольшую дополнительную работу. Есть несколько концептуальных вещей, которые нужно сначала убрать с пути:
В вашем случае это скорее всего означает:
Что вам нужно сделать, так это разумно ограничить ваши ярлыки. Оставьте ваши существующие ограничения (10-тпс пространства для другого вида) в покое, но добавьте еще одно ограничение: отодвиньте левые края ваших меток на 10 пунктов от левого края их суперпредставления с необязательным приоритетом (высокий приоритет по умолчанию, вероятно, будет работать хорошо).
Затем, когда вы хотите, чтобы они переместились влево, полностью удалите левое представление. Обязательное ограничение 10pt для левого представления исчезнет вместе с представлением, к которому оно относится, и у вас останется только высокоприоритетное ограничение, чтобы метки были на расстоянии 10 пунктов от их суперпредставления. На следующем проходе макета это должно заставить их расширяться влево, пока они не заполнят ширину суперпредставления, но для вашего промежутка вокруг краев.
Одно важное предостережение: если вы хотите, чтобы ваш левый вид снова отображался на картинке, вам нужно не только добавить его обратно в иерархию представлений, но и одновременно восстановить все его ограничения . Это означает, что вам нужен способ поместить ограничение 10pt между представлением и его метками обратно всякий раз, когда это представление отображается снова.
источник
|-(space)-[hidden(0)]-(space)-[visible]
эффективно|-(2*space)-[visible]
. Во-вторых, это представление может начать генерировать нарушения ограничений в зависимости от его собственного поддерева представления и ограничений - вы не можете гарантировать, что вы можете произвольно ограничить представление на ширине 0 и заставить его продолжать работать.|-[otherViews]-[eitherThis][orThis]-|
, но я столкнулся с этой проблемой в конце концов.Добавление или удаление ограничений во время выполнения - тяжелая операция, которая может повлиять на производительность. Однако есть более простая альтернатива.
Для вида, который вы хотите скрыть, установите ограничение ширины. Ограничьте другие взгляды с ведущим горизонтальным разрывом к этому представлению.
Чтобы скрыть, обновите
.constant
ограничение ширины до 0.f. Другие виды автоматически переместятся влево, чтобы занять позицию.Смотрите мой другой ответ здесь для более подробной информации:
Как изменить ограничения меток во время выполнения?
источник
Для тех, кто поддерживает только iOS 8+ , есть новое активное логическое свойство . Это поможет включить только необходимые ограничения динамически
PS Ограничение выхода должно быть сильным , а не слабым
Пример:
Также, чтобы исправить ошибку в раскадровке, вам нужно снять
Installed
флажок для одного из этих ограничений.UIStackView (iOS 9+)
Еще один вариант - обернуть ваши взгляды в
UIStackView
. Как только вид будет скрыт,UIStackView
будет автоматически обновляться макетисточник
UIStackView
автоматическиhidden
изменяет свои представления, когда свойство изменяется в любом из его подпредставлений (iOS 9+).Перейти к 11:48 в этом видео WWDC для демонстрации:
Тайны Авто Макета, Часть 1
источник
Мой проект использует пользовательский
@IBDesignable
подклассUILabel
(для обеспечения согласованности цвета, шрифта, вставок и т. Д.), И я реализовал что-то вроде следующего:Это позволяет подклассу меток принимать участие в автоматической компоновке, но при скрытии не занимать места.
источник
Для Google: основываясь на ответе Макса, чтобы решить проблему с заполнением, которую многие заметили, я просто увеличил высоту метки и использовал эту высоту в качестве разделителя вместо фактического заполнения. Эта идея может быть расширена для любого сценария, содержащего представления.
Вот простой пример:
В этом случае я сопоставляю высоту метки Author с соответствующим
IBOutlet
:и когда я устанавливаю высоту ограничения равным
0.0f
, мы сохраняем «отступ», потому что высота кнопки воспроизведения позволяет это сделать.источник
NSLayoutConstraint
я считаю, что вы хотите обновитьconstant
свойство вашегоauthorLabelHeight
.связать ограничение между пользовательским интерфейсом и метками как IBOutlet и установить для элемента приоритета меньшее значение, если установлено скрытое = ДА
источник
Я закончил тем, что создал 2 xibs. Один с левым обзором и один без него. Я зарегистрировал оба в контроллере и затем решил, что использовать во время cellForRowAtIndexPath.
Они используют один и тот же класс UITableViewCell. Недостатком является то, что между XIB есть некоторое дублирование контента, но эти ячейки довольно простые. Плюс в том, что у меня нет кучки кода для ручного управления удалением вида, обновлением ограничений и т. Д.
В общем, это, вероятно, лучшее решение, поскольку они технически отличаются друг от друга и поэтому должны иметь разные XIB.
источник
В этом случае я сопоставляю высоту метки Author с соответствующим IBOutlet:
и когда я устанавливаю высоту ограничения равной 0.0f, мы сохраняем «отступ», потому что высота кнопки воспроизведения позволяет это сделать.
источник
Используйте два UIStackView по горизонтали и вертикали, когда какое-то подпредставление в стеке скрыто, другие подпредставления стека будут перемещены, используйте Распределение -> Заполнить пропорционально для вертикального стека с двумя UILabel, и для первого UIView необходимо задать параметры ширины и высоты
источник
Попробуйте это, я реализовал ниже код,
У меня есть один вид на ViewController, в котором добавлены другие три вида. Когда любой вид скрыт, два других вида переместятся, выполните следующие шаги. ,
1. ViewController.h Файл
2.ViewController.m
Надеюсь, что эта логика поможет кому-то.
источник
В моем случае я установил постоянную высоту ограничения на
0.0f
а также установитьhidden
свойствоYES
.Чтобы снова показать представление (с подпредставлениями), я сделал наоборот: я установил постоянную высоты в ненулевое значение и установил
hidden
свойство вNO
.источник
Я буду использовать горизонтальное представление стека. Он может удалить кадр, когда подпредставление скрыто.
На изображении ниже красный вид является фактическим контейнером для вашего контента и имеет конечный интервал 10pt для оранжевого суперпредставления (ShowHideView), затем просто подключите ShowHideView к IBOutlet и покажите / спрячьте / удалите его программно.
источник
Это мое другое решение, использующее ограничение приоритета. Идея установить ширину 0.
создать вид контейнера (оранжевый) и установить ширину.
создайте представление контента (красный) и установите конечное пространство 10pt в superview (оранжевый). Обратите внимание на концевые пробелы, есть 2 концевых ограничения с разным приоритетом. Низкий (= 10) и Высокий (<= 10). Это важно, чтобы избежать двусмысленности.
Установите оранжевую ширину вида на 0, чтобы скрыть вид.
источник
Как и предположил no_scene, вы можете сделать это, изменив приоритет ограничения во время выполнения. Это было намного проще для меня, потому что у меня было более одного вида блокировки, который нужно было удалить.
Вот фрагмент кода с использованием ReactiveCocoa:
источник
Если это кому-то поможет, я создал вспомогательный класс для использования визуального формата ограничений . Я использую это в моем текущем приложении.
AutolayoutHelper
Это может быть немного приспособлено к моим потребностям, но вы можете найти это полезным или захотите изменить его и создать своего собственного помощника.
Я должен поблагодарить Тима за его ответ выше , этот ответ о UIScrollView, а также этот учебник .
источник
Вот как я бы выровнял свои uiviews, чтобы получить ваше решение:
Я создал собственное правило большого пальца. Всякий раз, когда вам нужно скрыть / показать какой-либо пользовательский вид, на чьи ограничения могут повлиять, добавьте все затронутые / зависимые подпредставления внутри пользовательского интерфейса и программно обновите его константу начальных / конечных / верхних / нижних ограничений.
источник
Это старый вопрос, но все же я надеюсь, что это поможет. Исходя из Android, на этой платформе у вас есть удобный метод,
isVisible
чтобы скрыть его от вида, но при этом не учитывать кадр, когда автопутешествие рисует вид.используя extension и "extension" uiview, вы можете сделать аналогичную функцию в ios (не уверен, почему его нет в UIKit), здесь реализация в swift 3:
источник
правильный способ сделать это - отключить ограничения с помощью isActive = false. заметьте, однако, что деактивация ограничения удаляет и освобождает его, поэтому вы должны иметь сильные выходы для них.
источник
Самое простое решение - использовать UIStackView (горизонтальный). Добавить в стек: первый вид и второй вид с метками. Затем установите для свойства isHidden первого вида значение false. Все ограничения будут рассчитаны и обновлены автоматически.
источник
Я думаю, что это самый простой ответ. Пожалуйста, убедитесь, что это работает:
проверьте здесь https://www.youtube.com/watch?v=EBulMWMoFuw
источник