метод sizeWithFont является устаревшим. boundingRectWithSize возвращает неожиданное значение


в iOS7, sizeWithFont является устаревшим, поэтому я использую boundingRectWithSize(который возвращает значение CGRect). Мой код:

 UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
                    // you can use your font.

 CGSize maximumLabelSize = CGSizeMake(310, 9999);

 CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                             options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{NSFontAttributeName:fontText}
                             context:nil];

 expectedLabelSize = CGSizeMake(textRect.size.width, textRect.size.height);

на textRect, Я получаю размер больше, чем мой maximumLabelSize, другой размер, чем при использовании sizeWithFont. Как я могу решить эту проблему?

6 78

6 ответов:

как насчет создания новой метки и использования sizeThatFit:(CGSize)size ??

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:@"YOUR FONT's NAME" size:16];
gettingSizeLabel.text = @"YOUR LABEL's TEXT";
gettingSizeLabel.numberOfLines = 0;
gettingSizeLabel.lineBreakMode = NSLineBreakByWordWrapping;
CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);

CGSize expectSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

Edit: этот верхний код не подходит для ios 7 и выше, поэтому, пожалуйста, используйте ниже:

CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                         options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
                         attributes:@{NSFontAttributeName:fontText}
                         context:nil];

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

CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                                         options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                      attributes:@{NSFontAttributeName: fontText}
                                         context:nil];

вот мой рабочий код:

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];

NSString *headline  = [dict objectForKey:@"title"];  
UIFont *font        = [UIFont boldSystemFontOfSize:18];  
CGRect  rect        = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];

CGFloat height      = roundf(rect.size.height +4)

я добавил 4px к расчетной высоте, потому что без этих 4px, есть одна строка отсутствует.

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

добавьте еще 4 пикселя, если вы хотите больше места под текстом в textLabel.

**** обновление ****

Я не согласен с "ширина ошибка 40px", я кричу быть 4px недостающей высоты, потому что 4px-это высота по умолчанию пространства между буквой и границей одной строки. Вы можете проверить это с помощью UILabel, для размера шрифта 16 вам нужна высота UILabel 20.

но если ваша последняя строка не имеет "g" или что-то в нем, измерение может быть пропущено 4px высоты.

я перепроверил его с небольшим методом, я получаю точную высоту 20,40 или 60 для моей метки и правой ширины меньше, чем 300 пикселей.

для поддержки iOS6 и iOS7, вы можете использовать мой метод:

- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
    CGRect rect;

    float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (iosVersion >= 7.0) {
        rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    }
    else {
        CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
        rect = CGRectMake(0, 0, size.width, size.height);
    }
    NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
    return rect.size.height;
}

**** обновление ****

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

- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
    CGRect rect;

    if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
        rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    }
    else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
        rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
    }
    return ceil(rect.size.height);
}

В дополнение к теме 4px: в зависимости от того, какой шрифт и вес шрифта вы используете, расчет возвращает различные значения высоты. В моем случае: HelveticaNeue-Medium с размером шрифта 16.0 возвращает высоту строки 20.0 для одной строки, но 39.0 для двух строк, 78px для 4 строк -> 1px отсутствует для каждой строки-начиная со строки 2-но вы хотите иметь свой размер шрифта + 4px linespace для каждой строки вы должны получить результат высоты.
пожалуйста, имейте это в виду при кодировании!
у меня еще нет функции для этой "проблемы", но я обновлю этот пост, когда я закончу.

Если я правильно понимаю, вы используете boundingRectWithSize: так же, как способ получить размер, который вы получите с sizeWithFont (то есть вы хотите непосредственно CGSize, а не CGRect)?

Это похоже на то, что вы ищете :

замена для устаревшего sizeWithFont: в iOS 7?

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

вы все еще получаете неправильный размер, используя что-то вроде этого :

UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
                    // you can use your font.

expectedLabelSize = [myString sizeWithAttributes:@{NSFontAttributeName:fontText}];

комментарий @SoftDesigner сработал для меня

CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
                                                       options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                    attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
                                                       context:nil];
result = ceil(descriptionRect.size.height);

для нахождения размера меткой времени sizewithfont считается устаревшим для iOS 7.0 вместо этого вы должны использовать - boundingRectWithSize:options:attributes: context: метод

вы можете использовать его как ниже код

CGSize constraint = CGSizeMake(MAXIMUM_WIDHT, TEMP_HEIGHT);
NSRange range = NSMakeRange(0, [[self.message body] length]);

NSDictionary *attributes = [YOUR_LABEL.attributedText attributesAtIndex:0 effectiveRange:&range];
CGSize boundingBox = [myString boundingRectWithSize:constraint options:NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
int numberOfLine = ceil((boundingBox.width) / YOUR_LABEL.frame.size.width);
CGSize descSize = CGSizeMake(ceil(boundingBox.width), ceil(self.lblMessageDetail.frame.size.height*numberOfLine));

CGRect frame=YOUR_LABEL.frame;
frame.size.height=descSize.height;
YOUR_LABEL.frame=frame;

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

попробуйте это, это работает для меня.