UILabel sizeToFit не работает с автозапуском ios6
Как мне настроить программным способом (и в каком методе) UILabel, чья высота зависит от его текста? Я пытался настроить его с помощью комбинации раскадровки и кода, но безрезультатно. Все рекомендуют sizeToFit
при настройке lineBreakMode
и numberOfLines
. Однако, независимо от того, помещаю ли я этот код в viewDidLoad:
, viewDidAppear:
или viewDidLayoutSubviews
, я не могу заставить его работать. Либо я делаю коробку слишком маленькой для длинного текста, и она не растет, или я делаю ее слишком большой, и она не сжимается.
Ответы
Ответ 1
Обратите внимание на, что в большинстве случаев Решение Matt работает как ожидалось. Но если это не сработает для вас, пожалуйста, прочтите дальше.
Чтобы сделать ваш ярлык автоматически измененным по высоте, вам необходимо выполнить следующие действия:
- Установить ограничения компоновки для метки
- Установить ограничение высоты с низким приоритетом. Он должен быть ниже, чем ContentCompressionResistancePriority
- Установить номерOfLines = 0
- Установить ContentHuggingPriority выше приоритета высоты надписи
- Задайте предпочтительнуюMaxLayoutWidth для метки. Это значение используется меткой для вычисления ее высоты
Например:
self.descriptionLabel = [[UILabel alloc] init];
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_([email protected])]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
Использование Interface Builder
-
Настройте четыре ограничения. Ограничение высоты является обязательным.
-
Затем перейдите к указателю атрибутов меток и установите количество строк в 0.
-
Перейдите к инспектору размера метки и увеличьте вертикальное содержание ContentHuggingPriority и вертикальное ContentCompressionResistancePriority.
-
Выбор и изменение ограничения высоты.
-
И уменьшите приоритет ограничения высоты.
Enjoy.:)
Ответ 2
В iOS 6, используя autolayout, если стороны UILabel (или ширина) и верхняя часть закреплены, она будет автоматически расти и сжиматься вертикально, чтобы соответствовать ее содержимому, без какого-либо кода и не вмешиваться в его сопротивление сжатию или что-то еще. Это мертво просто.
В более сложных случаях просто установите метку preferredMaxLayoutWidth
.
В любом случае, правильная вещь происходит автоматически.
Ответ 3
Несмотря на то, что в запросе указано программно, столкнувшись с той же проблемой и предпочитая работать в Interface Builder, я подумал, что было бы полезно добавить к существующим ответам решение Interface Builder.
Первое, что нужно забыть sizeToFit
. Автоматический макет будет обрабатывать это от вашего имени на основе внутреннего размера содержимого.
Таким образом, проблема заключается в том, как получить ярлык в соответствии с его содержимым с помощью Auto Layout? В частности - потому что вопрос упоминает об этом - рост. Обратите внимание, что те же самые принципы применяются к ширине.
Итак, давайте начнем с примера UILabel с высотой, установленной до 41px high:
Как вы можете видеть в захвате экрана выше, "This is my text"
имеет дополнение сверху и снизу. Это отступы между высотой UILabel и содержанием, текстом.
Если мы запустим приложение в симуляторе, то, конечно же, мы увидим одно и то же:
Теперь, выберите UILabel в Interface Builder и посмотрите настройки по умолчанию в инспекторе Size:
Обратите внимание на выделенное ограничение выше. Это Приоритет обхода контента. Как описывает Эрика Садун в отличном iOS Auto Layout Demystified, это:
способ просмотра предпочитает избегать дополнительного заполнения вокруг его основного содержимого
Для нас, с UILabel, основным содержанием является текст.
Здесь мы находимся в основе этого базового сценария. Мы дали нашему текстовому ярлыку два ограничения. Они конфликтуют. Один говорит: "высота должна быть равна 41 пикселю в высоту". Другой говорит: "Обнимайте представление о нем, чтобы у нас не было дополнительного дополнения". В нашем случае обхватите его текст, чтобы у нас не было дополнительного дополнения.
Теперь, с помощью Auto Layout, с двумя разными инструкциями, которые говорят о разных вещах, среда выполнения должна выбрать один или другой. Он не может сделать то и другое. UILabel не может быть как высотой 41 пиксель, так и без прокладки.
Как это разрешено, указывается приоритет. Одна инструкция должна иметь более высокий приоритет, чем другой. Если обе инструкции говорят разные вещи и имеют одинаковый приоритет, произойдет исключение.
Итак, дайте ему уйти. Ограничение по высоте имеет приоритет 1000, который требуется. Высота обнимания контента 250, слабая. Что произойдет, если мы уменьшим приоритет ограничения высоты до 249?
Теперь мы видим, как начинается волшебное начало. Попробуйте в симу:
Awesome! Достигнуто обход контента. Только потому, что приоритет по высоте 249 меньше приоритета 250. В основном, я говорю, что "высота, которую я указываю здесь, менее важна, чем то, что я указал для обхода содержимого". Таким образом, обнимание содержимого выигрывает.
Нижняя строка, чтобы метка соответствовала тексту, может быть такой же простой, как указание ограничения по высоте или ширине, и правильная настройка этого приоритета в связи с ограничением приоритета содержимого этой оси.
Оставим эквивалент ширины как упражнение для читателя!
Ответ 4
Замечено в IOS7 sizeToFit тоже не работает - возможно, решение может вам помочь.
[textView sizeToFit];
[textView layoutIfNeeded];
Ответ 5
Другим вариантом обеспечения метки labelMaxLayoutWidth поддерживается синхронизация с шириной метки:
#import "MyLabel.h"
@implementation MyLabel
-(void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
// This appears to be needed for iOS 6 which doesn't seem to keep
// label preferredMaxLayoutWidth in sync with its width, which
// means the label won't grow vertically to encompass its text if
// the label width constraint changes.
self.preferredMaxLayoutWidth = self.bounds.size.width;
}
@end
Ответ 6
Я чувствую, что должен внести свой вклад, поскольку мне потребовалось некоторое время, чтобы найти правильное решение:
- Цель состоит в том, чтобы Auto Layout выполнял свою работу, даже не называя sizeToFit(), мы сделаем это, указав правильные ограничения:
- Укажите ограничения верхнего, нижнего и верхнего/конечного пробелов на вашем UILabel
- Задайте для количества строк значение 0
- Увеличение приоритета обхода контента до 1000
- Оставшееся значение сопротивления сжатию содержимого до 500
- В нижнем контейнере ограничение, уменьшите приоритет до 500
В основном, происходит то, что вы указываете свой UILabel, что, хотя у него есть фиксированное ограничение по высоте, он может сделать ограничение, чтобы уменьшить его, чтобы обнять контент (если у вас есть одна строка, например) но он не может сломать ограничение, чтобы сделать его более крупным.
Ответ 7
В моем случае я создавал подкласс UIView, содержащий UILabel (неизвестной длины). В iOS7 код был прост: установите ограничения, не беспокойтесь об обжатии содержимого или сопротивлении сжатию, и все сработало, как ожидалось.
Но в iOS6 UILabel всегда был привязан к одной строке. Ни один из ответов выше не работал у меня. Параметры защиты содержимого и сжатия не учитывались. Единственное решение, которое предотвратило отсечение, состояло в том, чтобы включить на этикетке предпочтительнуюMaxLayoutWidth. Но я не знал, как установить предпочтительную ширину, поскольку размер его родительского представления неизвестен (действительно, он будет определяться содержимым).
Наконец я нашел решение здесь. Поскольку я работал над пользовательским представлением, я мог бы просто добавить следующий метод, чтобы установить предпочтительную ширину макета после того, как были рассчитаны ограничения один раз, а затем пересчитайте их:
- (void)layoutSubviews
{
// Autolayout hack required for iOS6
[super layoutSubviews];
self.bodyLabel.preferredMaxLayoutWidth = self.bodyLabel.frame.size.width;
[super layoutSubviews];
}
Ответ 8
Я решил с xCode6 поставить "Предпочтительную ширину" на "Автоматически" и нанести верхнюю и верхнюю метки верхнего и верхнего конца
Ответ 9
Я добавил программный код UILabel
, и в моем случае этого было достаточно:
label.translatesAutoresizingMaskIntoConstraints = false
label.setContentCompressionResistancePriority(UILayoutPriorityRequired, forAxis: .Vertical)
label.numberOfLines = 0
Ответ 10
UIFont *customFont = myLabel.font;
CGSize size = [trackerStr sizeWithFont:customFont
constrainedToSize:myLabel.frame.size // the size here should be the maximum size you want give to the label
lineBreakMode:UILineBreakModeWordWrap];
float numberOfLines = size.height / customFont.lineHeight;
myLabel.numberOfLines = numberOfLines;
myLabel.frame = CGRectMake(258, 18, 224, (numberOfLines * customFont.lineHeight));
Ответ 11
Я столкнулся с этой проблемой также с подклассом UIView, который содержит UILabel как один, если его внутренние элементы. Даже при автозапуске и использовании всех рекомендуемых решений метка просто не затягивала бы высоту текста. В моем случае, я только хочу, чтобы метка была одной строкой.
Во всяком случае, то, что сработало для меня, заключалось в том, чтобы добавить требуемое ограничение высоты для UILabel и установить его вручную на нужную высоту, когда вызывается intrinsicContentSize. Если у вас нет UILabel, содержащегося в другом UIView, вы можете попробовать подклассифицировать UILabel и предоставить аналогичную реализацию, сначала установив ограничение по высоте, а затем вернув
[super instrinsicContentSize]; вместо [self.containerview intrinsiceContentSize]; как я делаю ниже, что характерно для моего подлодка UIView.
- (CGSize)intrinsicContentSize
{
CGRect expectedTextBounds = [self.titleLabel textRectForBounds:self.titleLabel.bounds limitedToNumberOfLines:1];
self.titleLabelHeightConstraint.constant = expectedTextBounds.size.height;
return [self.containerView intrinsicContentSize];
}
Теперь отлично работает на iOS 7 и iOS 8.
Ответ 12
Решение, которое сработало для меня; Если ваш UILabel имеет фиксированную ширину, измените ограничение от constant =
до constant <=
в файле интерфейса
Ответ 13
В моем случае при использовании меток в UITableViewCell метка at изменит размер, но высота превысит высоту ячейки таблицы. Это то, что сработало для меня. Я сделал в соответствии с Max MacLeod, а затем убедился, что высота ячейки установлена в UITableViewAutomaticDimension.
Вы можете добавить это в свой init или awakeFromNib,
self.tableView.rowHeight = UITableViewAutomaticDimension.
В раскадровке выберите ячейку, откройте Инспектор размеров и убедитесь, что высота строки установлена на "По умолчанию", установив флажок "Пользовательский".
В 8.0 есть проблема, которая также требует, чтобы она была установлена в коде.