Как скорректировать размер шрифта маркировки для установки прямоугольнику?

Да, существует, это охлаждается myLabel.adjustsFontSizeToFitWidth = YES; свойство. Но как только маркировка имеет две строки или больше, она не изменит размер текста ни к чему. Таким образом, это просто становится усеченным с..., если это не вписывается в реагирование.

Там другой путь состоит в том, чтобы сделать это?

36
задан dontWatchMyProfile 16 May 2010 в 15:58
поделиться

2 ответа

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

Этот фрагмент начинается с 300 пунктов и пытается уместить метку в целевой прямоугольник за счет уменьшения размера шрифта.

- (void) sizeLabel: (UILabel *) label toRect: (CGRect) labelRect {

    // Set the frame of the label to the targeted rectangle
    label.frame = labelRect;

    // Try all font sizes from largest to smallest font size
    int fontSize = 300;
    int minFontSize = 5;

    // Fit label width wize
    CGSize constraintSize = CGSizeMake(label.frame.size.width, MAXFLOAT);

    do {
        // Set current font size
        label.font = [UIFont fontWithName:label.font.fontName size:fontSize];

        // Find label size for current font size
        CGRect textRect = [[label text] boundingRectWithSize:constraintSize
                                                     options:NSStringDrawingUsesLineFragmentOrigin
                                                  attributes:@{NSFontAttributeName: label.font}
                                                     context:nil];

        CGSize labelSize = textRect.size;

        // Done, if created label is within target size
        if( labelSize.height <= label.frame.size.height )
            break;

        // Decrease the font size and try again
        fontSize -= 2;

    } while (fontSize > minFontSize);
}

Я думаю, что вышесказанное объясняет, что происходит. Более быстрая реализация могла бы использовать кэширование и двоичный поиск argarcians следующим образом

+ (CGFloat) fontSizeForString: (NSString*) s inRect: (CGRect) labelRect  {
    // Cache repeat queries
    static NSMutableDictionary* mutableDict = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mutableDict = [NSMutableDictionary dictionary];
    });

    NSString* key = [NSString stringWithFormat:@"%@_%d_%d", s, (int) labelRect.size.width, (int) labelRect.size.height];
    NSNumber* value = [mutableDict objectForKey:key];
    if (value)
        return value.doubleValue;

    // Set the frame of the label to the targeted rectangle
    UILabel* label = [[UILabel alloc] init];
    label.text = s;
    label.frame = labelRect;

    // Hopefully between 5 and 300
    CGFloat theSize = (CGFloat) [self binarySearchForFontSizeForLabel:label withMinFontSize:5 withMaxFontSize:300 withSize:label.frame.size];
    [mutableDict setObject:@(theSize) forKey:key];
    return  theSize;
}


+ (NSInteger)binarySearchForFontSizeForLabel:(UILabel *)label withMinFontSize:(NSInteger)minFontSize withMaxFontSize:(NSInteger)maxFontSize withSize:(CGSize)size {
    // If the sizes are incorrect, return 0, or error, or an assertion.
    if (maxFontSize < minFontSize) {
        return maxFontSize;
    }

    // Find the middle
    NSInteger fontSize = (minFontSize + maxFontSize) / 2;
    // Create the font
    UIFont *font = [UIFont fontWithName:label.font.fontName size:fontSize];
    // Create a constraint size with max height
    CGSize constraintSize = CGSizeMake(size.width, MAXFLOAT);
    // Find label size for current font size
    CGRect rect = [label.text boundingRectWithSize:constraintSize
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                        attributes:@{NSFontAttributeName : font}
                                           context:nil];
    CGSize labelSize = rect.size;

    // EDIT:  The next block is modified from the original answer posted in SO to consider the width in the decision. This works much better for certain labels that are too thin and were giving bad results.
    if (labelSize.height >= (size.height + 10) && labelSize.width >= (size.width + 10) && labelSize.height <= (size.height) && labelSize.width <= (size.width)) {
        return fontSize;
    } else if (labelSize.height > size.height || labelSize.width > size.width) {
        return [self binarySearchForFontSizeForLabel:label withMinFontSize:minFontSize withMaxFontSize:fontSize - 1 withSize:size];
    } else {
        return [self binarySearchForFontSizeForLabel:label withMinFontSize:fontSize + 1 withMaxFontSize:maxFontSize withSize:size];
    }
}
49
ответ дан 27 November 2019 в 05:22
поделиться

Также установите myLabel.numberOfLines = 10 или любое другое максимальное количество строк, которое вы хотите.

1
ответ дан 27 November 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: