Как изменить ограничения метки во время выполнения?

У меня есть табличный вид и ячейка внутри него. Ячейка содержит три метки: метку заголовка и две метки ниже друг друга. Иногда мне нужно скрыть эти два ярлыка ниже, если они не содержат данных и изменить "Верхнее пространство в контейнере" "Ярлык заголовка" на "Центр Y в контейнер". И, конечно, верните ограничения, когда два ярлыка содержат данные. Вот скриншот простого демонстрационного проекта только для демонстрации идеи:

enter image description here

ОБНОВЛЕНИЕ Максимальный ответ MacLeod указывает на правильное направление. Хитрость заключается в том, чтобы нажимать метку заголовка вниз, когда первая и вторая метки скрыты. Поэтому нам нужно установить нижнее пространство в представление контейнера для первой и второй меток вместо создания верхнего пространства для представления контейнера для метки заголовка. И скрытие/скрытие должно выполняться за счет наличия розеток (ограничений по высоте для первой и второй метки) и установки их постоянных значений на ноль (и установка значения обратной связи при отображении). Я также загрузил пример исходного кода в Github.

Ответ 1

Выберите метку заголовка и одну из нижних меток и добавьте новое ограничение вертикального пространства, отражающее разрыв между ними. Затем удалите метку заголовка Верхнее пространство для ограничения контейнера. Возможно, у вас уже есть это (не видно из экрана). Если да, то хорошо.

Теперь создайте два ограничения высоты для каждой нижней метки. IBOutlet для вашего класса.

Затем скройте эти две нижние метки, когда вам нужно, установив каждое ограничение по высоте constant на 0.f.

Это сделает их невидимыми и опустит верхнюю метку заголовка выше, чтобы теперь она была вертикально центрирована Y в контейнере.

Повторите шаги еще раз (слишком долго для комментария!). Последовательность имеет значение с IB, поскольку сначала вы должны добавить новое ограничение, прежде чем сможете удалить старый. Временно у вас будет одно избыточное ограничение. Это потому, что IB не допустит двусмысленности. Итак, сначала добавьте новое ограничение вертикального пространства. Это определит положение Y верхней метки. Затем удалите избыточное вертикальное пространство для ограничения контейнера с верхней метки. Теперь эта метка будет располагаться Y, используя вертикальное пространство относительно нижних меток. Затем добавьте ограничения высоты для каждой нижней метки и ссылку на класс с IBOutlet. Еще одна вещь, на самом деле вам понадобятся нижние метки, которые должны быть ограничены контейнером с ограничением нижнего пространства. Когда их высота уменьшается до нуля, они исчезнут, а верхняя метка будет двигаться ниже, чтобы принять положение Y-центра.

Чтобы вернуться, просто верните constant к исходному значению.

Это гораздо лучший подход, чем добавление/удаление ограничений, что является тяжеловесной операцией. Обратите внимание, что вы можете добавить две нижние метки в представление "контейнер", чтобы они могли отображаться/скрываться как одна. Кроме того, он должен был бы убрать код, так как вы действительно хотите, чтобы вертикальное пространство находилось между вашей верхней меткой, и обе нижние метки, а не только одна.

См. также мой ответ Автозапуск со скрытыми UIView?

Ответ 2

Поместите ярлыки, которые вы хотите скрыть, в представление, как только все будет иметь правильные ограничения макета, добавьте ограничение высоты в представление контейнера и подключите ограничение к свойству IBOutlet.

Убедитесь, что ваши свойства strong

в коде yo просто нужно установить константу в 0 и активировать ее, скрывать содержимое или деактивировать ее, чтобы показать содержимое. Это лучше, чем испортить постоянную ценность, сохраняя-восстанавливая ее. Не забудьте позже позвонить layoutIfNeeded.

@property (strong, nonatomic) IBOutlet UIView *myContainer;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *myContainerHeight; //should be strong!!

-(void) showContainer
{
    self.myContainerHeight.active = NO;
    self.myContainer.hidden = NO;
    [self.view layoutIfNeeded];
}
-(void) hideContainer
{
    self.myContainerHeight.active = YES;
    self.myContainerHeight.constant = 0.0f;
    self.myContainer.hidden = YES;
    [self.view layoutIfNeeded];
}

Как только у вас есть настройки, вы можете протестировать его в IntefaceBuilder, установив ограничение на 0, а затем обратно на исходное значение. Не забудьте проверить приоритеты других ограничений, поэтому, когда скрыты, конфликт вообще отсутствует. другой способ проверить это, чтобы поставить его в 0 и установить приоритет 0, но вы не должны забывать восстановить его с наивысшим приоритетом снова.

Ответ 3

Я сам что-то очень люблю. Поэтому добавьте ограничение ширины к обоим меткам. Вы можете изменить постоянное значение, пока применяется ограничение - просто держите ссылку на него. В моем случае у меня есть массив, в который я помещаю ограничения, которые планирую изменить.

Если вы хотите скрыть метки, измените значение c на 0 - вы можете сделать это и в блоке анимации. Чтобы показать изменение значения.

Вы также можете сделать ширину верхнего пространства равным нижнему пространству, поэтому, когда представления скрываются или отображаются, вы сохраняете "группу" элементов по центру.

Обратите внимание, что вы можете добавлять или удалять ограничения, но более дорогостоящие для iOS.

Ответ 4

Редко вы можете легко понять, а некоторые практические примеры, когда дело до Apple Documentation, но это точный случай исключения в правиле.

Я лично нашел этот документ настолько понятным и понятным. Лучший способ стать гуру автомакетов во времени:)

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutinCode/AutoLayoutinCode.html

В основном, время выполнения означает "программно".

Итак, ответ на ваш вопрос лежит здесь:

fooobar.com/info/27793/...