Вопрос по uilabel, nsstring, ios, objective-c – Как узнать, подходит ли NSString в UILabel или нет, и индекс последней подходящей строки?

5

У меня 4 строки UILabel с точной рамкой и шрифтом.

Мне нужно знать, соответствует ли эта строка метке и каков индекс последнего символа, который подходит.

Сначала я посмотрел на это, но это не помогло B.S.
ответ @Cupcake, размещенный здесь, должен помочь вам Omar Abdelhafith
Этот вопрос должен помочь вам:stackoverflow.com/questions/6422742/… Thomas Clemensen

Ваш Ответ

1   ответ
9

вы можете использоватьsizeWithFont:constrainedToSize:lineBreakMode: чтобы выяснить, какой будет размер рамки с конкретным шрифтом в метке заданной ширины при заданном переносе слов, например,

CGSize size = [string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:UILineBreakModeWordWrap];

ЗадаватьsizeConstraint чтобы быть такой же ширины вашей метки, но установить высоту, чтобы быть больше. Если в результатеsize.height больше, чем ваша UILabel, тогда ваша строка слишком длинная. Теоретически, вы можете удалить последний символ / слово и попробовать еще раз и повторять, пока он не подходит.

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

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

Update:

Вот алгоритм, который возвращает длинуNSString которые могут вписаться вUILabel в вопросе используется шрифт по умолчанию (но игнорируется минимальный размер шрифта):

- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
    UIFont *font           = label.font;
    UILineBreakMode mode   = label.lineBreakMode;

    CGFloat labelWidth     = label.frame.size.width;
    CGFloat labelHeight    = label.frame.size.height;
    CGSize  sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);

    if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight) 
    {
        NSString *adjustedString;

        for (NSUInteger i = 1; i < [string length]; i++) 
        {
            adjustedString = [string substringToIndex:i];

            if ([adjustedString sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
                return i - 1;
        }
    }

    return [string length];
}

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

- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
    UIFont *font           = label.font;
    UILineBreakMode mode   = label.lineBreakMode;

    CGFloat labelWidth     = label.frame.size.width;
    CGFloat labelHeight    = label.frame.size.height;
    CGSize  sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);

    if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight) 
    {
        NSUInteger index = 0;
        NSUInteger prev;
        NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];

        do 
        {
            prev = index;
            if (mode == UILineBreakModeCharacterWrap)
                index++;
            else
                index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
        }
        while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height <= labelHeight);

        return prev;
    }

    return [string length];
}

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

Этот метод теперь устарел, поэтому вы можете использовать - (CGRect) boundingRectWithSize: (CGSize) параметры размера: (NSStringDrawingOptions) контекст параметров: (NSStringDrawingContext *) context NS_AVAILABLE_IOS (6_0); вместо
Большое спасибо! B.S.

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