UILabel не автоматически сжимает текст после назначения NSAttributedString

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

[_commentsLabel setAttributedText:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%d comments", [comments count]] attributes:@{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)}]];

Как видите, количество комментариев будет определять длину текста. Но почему-то текст не сжимается. Минимальный масштаб шрифта установлен на 0,1 и установлен флажок «Уменьшить межбуквенный интервал».

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


person Guilherme    schedule 21.01.2014    source источник


Ответы (3)


Я бы попробовал установить свойство labels

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

на YES и посмотрите, решит ли это проблему. Дайте мне знать, если нет. У меня была проблема в другой ситуации, но в итоге я использовал код для изменения размера вручную.

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

    - (CGFloat)requiredFontSizeForLabel:(UILabel *)label
{
    if (!label) {
        return kFontSize;
    }
    CGFloat originalFontSize = kFontSize;

    UIFont* font = label.font;
    CGFloat fontSize = originalFontSize;

    BOOL found = NO;
    do
    {
        if( font.pointSize != fontSize )
        {
            font = [font fontWithSize: fontSize];
        }
        if([self wouldThisFont:font workForThisLabel:label])
        {
            found = YES;
            break;
        }

        fontSize -= 0.5;
        if( fontSize < (label.minimumScaleFactor * label.font.pointSize))
        {
            break;
        }

    } while( TRUE );

    return( fontSize );
}

    - (BOOL) wouldThisFont:(UIFont *)testFont workForThisLabel:(UILabel *)testLabel {
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:testFont, NSFontAttributeName, nil];
    NSAttributedString *as = [[NSAttributedString alloc] initWithString:testLabel.text attributes:attributes];
    CGRect bounds = [as boundingRectWithSize:CGSizeMake(CGRectGetWidth(testLabel.frame), CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) context:nil];
    BOOL itWorks = [self doesThisSize:bounds.size fitInThisSize:testLabel.bounds.size];
    return itWorks;
}

        - (BOOL)doesThisSize:(CGSize)aa fitInThisSize:(CGSize)bb 
    {
        if ( aa.width > bb.width ) return NO;
        if ( aa.height > bb.height ) return NO;
        return YES;
    }

Источник кода, найденный здесь

person horsejockey    schedule 21.01.2014
comment
Я так пробовал, безуспешно. Кажется, это проблема с NSAttributedStrings. Он работает с обычными NSString. - person Guilherme; 21.01.2014
comment
@Guilherme, вот код, который я использовал, когда у меня не работало масштабирование. Может быть, это может помочь вам. - person horsejockey; 21.01.2014
comment
Я не проверял это, но, похоже, это работает. Я закончил настраивать шрифт вручную в зависимости от количества комментариев, это было не слишком сложно. Если никто не предложит лучшего ответа/объяснения того, почему строки с атрибутами не сокращаются, я отмечу их как правильные. - person Guilherme; 22.01.2014

Строки атрибутов имеют собственный размер шрифта. Сделайте это вручную.

Все строки с атрибутами, составляющие строку с атрибутами, должны иметь NSFontAttributeName.

func updateLabelSizeIfNeeded() {
    let maxScale: CGFloat = 0.65
    let bounding = self.label.attributedText!.boundingRectWithSize(CGSizeMake(CGFloat.infinity, CGFloat.infinity), options: [], context: nil)
    if bounding.size.width > self.bounds.size.width*maxScale {
        let scaleFactor = (self.bounds.size.width * maxScale) / bounding.size.width

        label.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor)
    } else {
        label.transform = CGAffineTransformIdentity
    }
}
person seo    schedule 28.01.2016
comment
Это должен быть принятый ответ. Большое спасибо! - person kmell96; 23.10.2020

Я делаю это с помощью цикла:

while TheWidthOfSuperview < MyLabel.intrinsicContentSize.width {

    MyLabel.font = MyLabel.font.withSize(MyLabel.font.pointSize - 1)

}
person Miguel Herrero    schedule 15.10.2020