Динамически изменяемый размер шрифта UILabel - PullRequest
178 голосов
/ 01 февраля 2011

У меня в настоящее время есть UILabel:

factLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 280, 100)];
factLabel.text = @"some text some text some text some text";
factLabel.backgroundColor = [UIColor clearColor];
factLabel.lineBreakMode = UILineBreakModeWordWrap;
factLabel.numberOfLines = 10;
[self.view addSubview:factLabel];

На протяжении всей жизни моего приложения для iOS factLabel получает кучу разных значений.Некоторые с несколькими предложениями, другие только с 5 или 6 словами.

Как настроить UILabel так, чтобы размер шрифта изменялся так, чтобы текст всегда соответствовал границам, которые я определил?

Ответы [ 12 ]

0 голосов
/ 10 апреля 2016

Это решение работает для мультилинии:

После нескольких статей, когда мне потребовалась функция, которая автоматически масштабировала бы текст и корректировала счетчик строк в соответствии с заданным размером метки, я сам написал функцию. (т. е. короткая строка прекрасно помещалась бы на одной строке и использовала бы большую часть кадра метки, тогда как длинная сильная автоматически разбивалась на 2 или 3 строки и соответственно изменяла размер)

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

+ (void)setFontForLabel:(UILabel *)label withMaximumFontSize:(float)maxFontSize andMaximumLines:(int)maxLines {
    int numLines = 1;
    float fontSize = maxFontSize;
    CGSize textSize; // The size of the text
    CGSize frameSize; // The size of the frame of the label
    CGSize unrestrictedFrameSize; // The size the text would be if it were not restricted by the label height
    CGRect originalLabelFrame = label.frame;

    frameSize = label.frame.size;
    textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize: fontSize]}];

    // Work out the number of lines that will need to fit the text in snug
    while (((textSize.width / numLines) / (textSize.height * numLines) > frameSize.width / frameSize.height) && (numLines < maxLines)) {
        numLines++;
    }

    label.numberOfLines = numLines;

    // Get the current text size
    label.font = [UIFont systemFontOfSize:fontSize];
    textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX)
                                        options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                     attributes:@{NSFontAttributeName : label.font}
                                        context:nil].size;

    // Adjust the frame size so that it can fit text on more lines
    // so that we do not end up with truncated text
    label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width, label.frame.size.width);

    // Get the size of the text as it would fit into the extended label size
    unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size;

    // Keep reducing the font size until it fits
    while (textSize.width > unrestrictedFrameSize.width || textSize.height > frameSize.height) {
        fontSize--;
        label.font = [UIFont systemFontOfSize:fontSize];
        textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX)
                                            options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                         attributes:@{NSFontAttributeName : label.font}
                                            context:nil].size;
        unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size;
    }

    // Set the label frame size back to original
    label.frame = originalLabelFrame;
}
0 голосов
/ 16 марта 2016

Swift 2.0 Версия:

private func adapteSizeLabel(label: UILabel, sizeMax: CGFloat) {
     label.numberOfLines = 0
     label.lineBreakMode = NSLineBreakMode.ByWordWrapping
     let maximumLabelSize = CGSizeMake(label.frame.size.width, sizeMax);
     let expectSize = label.sizeThatFits(maximumLabelSize)
     label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, expectSize.width, expectSize.height)
}
...