Динамический UILabel с пропорциональной шириной и текстовой высотой

Я пытаюсь программно создать представление контейнера с двумя подпредставлениями UILabel, которые ведут себя следующим образом:

  • Ширина контейнера привязана к его супервизору; его высота ограничена, чтобы соответствовать этикеткам
  • Этикетки располагаются горизонтально со стандартным интервалом между ними (8 точек).
  • Ширина левой этикетки составляет 25% от ширины контейнера.
  • Правильная ширина этикетки заполняет доступное пространство за вычетом стандартного горизонтального интервала.
  • Длинный текст следует разрывать по границам слова, перемещаться по нескольким строкам; обе метки должны расти вертикально, чтобы вместить длинный текст

Я определил ярлыки с помощью numberOfLines = 0 и lineBreakMode = NSLineBreakByWordWrapping.

Обратите внимание, что размер контейнера полностью динамический; его ширина определяется его супервизором, а его высота определяется его подпредставлениями (метками). Размер меток также является динамическим; их ширина пропорциональна ширине контейнера, а их высота зависит от длины текста.

Мне удалось добиться всего, что указано выше, за исключением последнего элемента, со следующими ограничениями (псевдокод). A - левая метка, B - правая.

  • A.top == container.top
  • B.top == container.top
  • A.leading = container.leading
  • A.trailing == B.leading - 8
  • B.trailing == container.trailing
  • A == 0,25 * ширина контейнера
  • container.height> = A.height
  • container.height> = B.height

Последние 2 ограничения предназначены для того, чтобы растянуть контейнер, чтобы он соответствовал более высокой из этикеток, но механизм компоновки, похоже, игнорирует тот факт, что этикетки могут быть многострочными. То есть я всегда получаю одну строку, независимо от длины текста.

Итак, какие ограничения мне нужно добавить / изменить / удалить, чтобы достичь полного набора поведений, описанных выше?


person lencharest    schedule 04.12.2012    source источник
comment
Я бы посоветовал создать действительно простой демонстрационный проект с одним представлением, в котором он определен, и опубликовать его в Dropbox (или его эквиваленте). Если вы можете получить несколько очков, награда в размере 50 действительно привлекает много внимания и здесь. Две идеи, которые стоит выкинуть - вы можете попросить изменить размер метки с учетом ее текущего содержимого (или спросить у нее размер, который необходим), вы можете указать системе автоматического размещения, чтобы она изменила макет, и если вы реализуете текстовые делегаты, вы узнаете когда текст меняется. У меня сегодня нет опыта работы с автопрокладкой, но я активно читаю об этом.   -  person David H    schedule 05.12.2012
comment
Разрабатываю в MonoTouch. Я не думаю, что демо-версия C # будет полезна большинству гуру автоматического раскладки. :-(   -  person lencharest    schedule 05.12.2012


Ответы (3)


Чтобы ваши метки автоматически меняли высоту, вам необходимо сделать следующее:

  1. Установите ограничения макета для метки (это то, что вы на самом деле сделали)
  2. Установите ограничение высоты с низким приоритетом. Он должен быть лучше ContentCompressionResistancePriority
  3. Установить numberOfLines = 0
  4. Установите ContentHuggingPriority выше, чем высокий приоритет метки
  5. Установите предпочтительныйMaxLayoutWidth для метки. Это значение используется меткой для вычисления его высоты.

Например:

self.descriptionLabel = [[[UILabel alloc] init] autorelease];
self.descriptionLabel.numberOfLines = 0;
self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.descriptionLabel.preferredMaxLayoutWidth = 200;

[self.descriptionLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:self.descriptionLabel];

NSArray* constrs = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[descriptionLabel_]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)];
[self addConstraints:constrs];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[descriptionLabel_]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
[self.descriptionLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[descriptionLabel_(220@300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
person Mark Kryzhanouski    schedule 18.12.2012
comment
У меня не работает. stackoverflow.com/questions/22172572/ - person Geek; 05.03.2014
comment
preferredMaxLayoutWidth был для меня ключом - person atulkhatri; 02.08.2017

Установите приоритет ограничений по высоте для меток на низкое значение и попробуйте установить ограничения в коде.

person Sandeep Ankam    schedule 05.12.2012
comment
Я уже все делаю в коде. И приоритет не является проблемой; существующий набор ограничений выполним. - person lencharest; 05.12.2012

Убедитесь, что вы установили

  1. Приоритет сопротивления сжатию содержимого по горизонтали и вертикали. Если вы не хотите, чтобы метка усекала свое содержимое, установите для него значение 1000. т.е. required.
  2. Приоритет поддержки содержания. Посмотрите этот ответ, чтобы понять, как он работает.
person Geek    schedule 05.03.2014