it-swarm.com.ru

UILabel не сжимает текст автоматически до размера этикетки

У меня есть эта странная проблема, и я занимаюсь этим уже более 8 часов. В зависимости от ситуации мне нужно динамически вычислять размер UILabels,
например 
мой UIViewController получает событие, и я изменяю размер UILabels. от большего к меньшему. Размер моего UILabel становится меньше, и я получаю правильный необходимый размер, но текст в моем UILabel остается прежним, тот же размер шрифта и т.д. Мне нужно, чтобы шрифт уменьшился, чтобы весь текст соответствовал UILabel. Итак, вопрос в том, как сделать так, чтобы текст соответствовал моему ярлыку с autoshrinking или что-то в этом роде?

В моем xib проверяется UILabelsautoshrink, также число строк установлено в 0, а также в моей строке есть новые символы строки (\ n), и я выбрал linebreakmode для wordwrap. Может быть, кто-то был в такой же ситуации, как я сейчас, и мог бы помочь мне? Я был бы очень признателен.

Заранее спасибо!

Правка: UILabel минимальный размер шрифта установлен на 10

98
Lukas

Если вы все еще ищете лучшее решение, я думаю, это то, что вы хотите:

Логическое значение, указывающее, должен ли быть уменьшен размер шрифта, чтобы вписать строку заголовка в ограничивающий прямоугольник метки. (Это свойство действует только в том случае, если для свойства numberOfLines установлено значение 1.)

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

Логическое значение, указывающее, следует ли корректировать интервал между буквами, чтобы он соответствовал строке внутри прямоугольника границ метки.

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

Источник .

146
lester

Вот как я работаю с UILabel Autoshrink (особенно для высоты подгонки шрифта надписи на устройстве 4s от 6s Plus Storyboard) в iOS 9.2, Xcode 7.2 ...

 enter image description here

  • Количество строк 0
  • Разрывы строк: клип
  • Автоусадка: минимальный масштаб шрифта 0,25
105
ohho

minimumFontSize устарела в iOS 6.

Поэтому используйте minimumScaleFactor вместо minmimumFontSize.

lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;
60
user2681543

также мое решение - логическое label.adjustsFontSizeToFitWidth = YES; НО. В интерфейсе Builder необходимо установить переключатель «Обтекание словами» на «CLIP» . Затем автоматически сжимать метки. Это очень важно.

18
loki-e

Вы можете написать как

UILabel *reviews = [[UILabel alloc]initWithFrame:CGRectMake(14, 13,270,30)];//Set frame
reviews.numberOfLines=0;
reviews.textAlignment = UITextAlignmentLeft;
reviews.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:12];
reviews.textColor=[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.8]; 
reviews.backgroundColor=[UIColor clearColor];

Вы можете рассчитать количество строк, как это

CGSize maxlblSize = CGSizeMake(270,9999);
CGSize totalSize = [reviews.text sizeWithFont:reviews.font 
              constrainedToSize:maxlblSize lineBreakMode:reviews.lineBreakMode];

CGRect newFrame =reviews.frame;
newFrame.size.height = totalSize.height;
reviews.frame = newFrame;

CGFloat reviewlblheight = totalSize.height;

int lines=reviewlblheight/12;//12 is the font size of label

UILabel *lbl=[[UILabel alloc]init];
lbl.frame=CGRectMake(140,220 , 100, 25);//set frame as your requirement
lbl.font=[UIFont fontWithName:@"Arial" size:20];
[lbl setAutoresizingMask:UIViewContentModeScaleAspectFill];
[lbl setLineBreakMode:UILineBreakModeClip];
lbl.adjustsFontSizeToFitWidth=YES;//This is main for shrinking font
[email protected]"HelloHelloHello";

Надеюсь, что это поможет вам: -) Жду вашего ответа 

5
Birju

Это для Swift 3 под управлением Xcode 8.2.1 (8C1002) 

Лучшее решение, которое я нашел, это установить фиксированную ширину в раскадровке или IB на этикетке. Установите ваши ограничения с ограничением на полях. В ваш viewDidLoad добавьте следующие строки кода:

override func viewDidLoad() {
            super.viewDidLoad()

            label.numberOfLines = 1
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.5
        }

 label constraints to margin

 fixed width label constraints to margin

 attributes inspector

Это работает как шарм, и оно не переходит на новую строку и сокращает текст до ширины надписи без каких-либо странных проблем и работает в Swift 3.

4
Robert Mcelvenny

В Swift 3 (программно) я должен был сделать это:

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)
4
Naloiko Eugene

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

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

Я не понимаю, почему это так сложно реализовать. Если я что-то упустил, каждый может поправить меня :)

3
Lukas

Я думаю, что вы можете написать ниже код после alloc init Label 

UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, 280, 50)];
lbl.text = @"vbdsbfdshfisdhfidshufidhsufhdsf dhdsfhdksbf hfsdh fksdfidsf sdfhsd fhdsf sdhfh sdifsdkf ksdhfkds fhdsf dsfkdsfkjdhsfkjdhskfjhsdk fdhsf ";
[lbl setMinimumFontSize:8.0];
[lbl setNumberOfLines:0];
[lbl setFont:[UIFont systemFontOfSize:10.0]];
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.backgroundColor = [UIColor redColor];
[lbl sizeToFit];
[self.view addSubview:lbl];

Это работает со мной нормально Используйте его

2
iDhaval

Два года спустя, и эта проблема все еще существует ...

В iOS 8/XCode 6.1 я иногда обнаруживал, что мой UILabel (созданный в UITableViewCell, с включенным AutoLayout и гибкими ограничениями, чтобы в нем было достаточно места) не изменял свой размер, чтобы соответствовать текстовой строке.

Решение, как и в предыдущие годы, состояло в том, чтобы установить текст и затем call sizeToFit.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    . . .
    cell.lblCreatedAt.text = [note getCreatedDateAsString];
    [cell.lblCreatedAt sizeToFit];
}

(Вздох.)

2
Mike Gledhill

В iOS 9 мне просто нужно было:

  1. Добавьте ограничения слева и справа от метки в суперпредставление.
  2. Установите режим разрыва строки в отсечение в IB.
  3. Установите количество строк в 1 в IB.

Кто-то порекомендовал установить число строк равным 0, но для меня это просто заставило ярлык перейти на несколько строк ...

2
Nick Yap

Это отличный вопрос, потому что кажется, что это будет частью встроенной функциональности UIKit или связанной с ней инфраструктуры. Вот хороший наглядный пример вопроса:

Font resizing animation

Там нет простого пути, но это определенно возможно. Один из способов сделать это - программно пробовать шрифты разных размеров, пока не найдете тот, который подходит достаточно близко к границам вида. Вы можете сделать это с помощью функции boundingRect()NSString или NSAttributedString. Например:

let string = "This is a test"
let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height:CGFloat.greatestFiniteMagnitude)
let size = string.boundingRect(with: infiniteSize, options: [], attributes: [.font: UIFont.systemFont(ofSize: avgSize)] context: nil).size

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

Если вам нужно просто показать текст на экране, я разработал надежную реализацию в Swift, которую я также использую в производственном приложении. Это подкласс UIView с эффективным автоматическим масштабированием шрифта для любого вводимого текста, включая несколько строк. Чтобы использовать его, вы просто должны сделать что-то вроде:

let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere

Это оно! Вы можете найти полный источник здесь: https://github.com/FlickType/AccessibilityKit

Надеюсь это поможет!

1
Kosta Eleftheriou

не работает, если numberOfLines > 1 То, что я сделал, поставило условие

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];
1
Vaibhav Saran

Вот как это сделать. Предположим, что следующее messageLabel - это метка, которую вы хотите получить желаемый эффект. Теперь попробуйте эти простые строки кода:

    //SET THE WIDTH CONSTRAINTS FOR LABEL.
    CGFloat constrainedWidth = 240.0f;//YOU CAN PUT YOUR DESIRED ONE,THE MAXIMUM WIDTH OF YOUR LABEL.
 //CALCULATE THE SPACE FOR THE TEXT SPECIFIED.
    CGSize sizeOfText=[yourText sizeWithFont:yourFont constrainedToSize:CGSizeMake(constrainedWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    UILabel *messageLabel=[[UILabel alloc] initWithFrame:CGRectMake(20,20,constrainedWidth,sizeOfText.height)];
    messageLabel.text=yourText;
    messageLabel.numberOfLines=0;//JUST TO SUPPORT MULTILINING.
1
Anand

Опаздываю на вечеринку, но так как у меня было дополнительное требование иметь одно слово в строке, это одно дополнение помогло мне:

label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;

Apple Docs сказать:

Обычно текст метки рисуется шрифтом, который вы указали в свойстве font. Однако если для этого свойства задано значение YES, а текст в свойстве text превышает ограничивающий прямоугольник метки, получатель начинает уменьшать размер шрифта до тех пор, пока строка не будет соответствовать или не будет достигнут минимальный размер шрифта. В iOS 6 и более ранних версиях это свойство действует только в том случае, если для свойства numberOfLines установлено значение 1.

Но это ложь. Ложь, я говорю вам! Это верно для всех версий iOS. В частности, это верно при использовании UILabel внутри UICollectionViewCell, размер которого определяется ограничениями, динамически настраиваемыми во время выполнения с помощью пользовательского макета (например, self.menuCollectionViewLayout.itemSize = size).

Таким образом, при использовании в сочетании с adjustsFontSizeToFitWidth и minimumScaleFactor, как упоминалось в предыдущих ответах, программная установка numberOfLines на основе количества слов решает проблему автоматического сжатия. Выполнение чего-либо подобного на основе количества слов или даже количества символов может привести к «достаточно близкому» решению.

0
Justin Whitney

В Swift 4 (программно): 

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200.0, height: 200.0))
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0

label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

view.addSubview(label)
0
Hadži Lazar Pešić

Swift 4, Xcode 9.4.1

Решение, которое сработало для меня: У меня была метка в ячейке представления коллекции , и текст метки обрезался .. Установите атрибуты, как показано ниже на раскадровке

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
0
Naishta