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


146

В iOS 7 метод:

- (CGSize)sizeWithFont:(UIFont *)font
     constrainedToSize:(CGSize)size
         lineBreakMode:(NSLineBreakMode)lineBreakMode 

и метод:

- (CGSize)sizeWithFont:(UIFont *)font

устарели. Как я могу заменить

CGSize size = [string sizeWithFont:font
                 constrainedToSize:constrainSize
                     lineBreakMode:NSLineBreakByWordWrapping];

и:

CGSize size = [string sizeWithFont:font];

2
метод замены есть -sizeWithAttributes:.
Holex

Хорошо, спасибо, но как я могу использовать шрифт из метки, как NSDIctionary? если мой код похож на: sizeWithFont: customlabel.font; void ask "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo

1
Вот официальная документация о том, как вы можете определить атрибуты: developer.apple.com/library/ios/documentation/UIKit/Reference/…
holex

Ответы:


219

Вы можете попробовать это:

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:FONT}
                                 context:nil];

CGSize size = textRect.size;

Просто измените «FONT» на «[UIFont font ....]»


13
И где вы упоминаете NSLineBreakByWordWrapping? Куда это делось?
user4951

32
NSLineBreakByWordWrappingбудет идти в пределах NSParagraphStyle. Так, например: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;в атрибуты, которые вам нужно будет добавить NSParagraphStyleAttributeName: paragraphStyle.copy...
Флориан Фридрих

1
@fried в моем случае добавление параграфа Стиль с разрывом строки, отличным от NSLineBreakByWordWrapping, заставило вычислять размер только для одной строки ... Есть мысли?
Manicaesar

9
Не забывайте, что boundingRectWithSize:options:attributes:context:возвращает дробные значения. Вам нужно сделать ceil(textRect.size.height)и ceil(textRect.size.width)соответственно получить реальную высоту / ширину.
Флориан Фридрих

20
Какого черта BOLIVIASize?
JRam13

36

Поскольку мы не можем использовать sizeWithAttributes для всех iOS более 4.3, мы должны написать условный код для 7.0 и предыдущих версий iOS.

1) Решение 1:

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
   CGSize size = CGSizeMake(230,9999);
   CGRect textRect = [specialityObj.name  
       boundingRectWithSize:size
                    options:NSStringDrawingUsesLineFragmentOrigin
                 attributes:@{NSFontAttributeName:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14]}
                    context:nil];
   total_height = total_height + textRect.size.height;   
}
else {
   CGSize maximumLabelSize = CGSizeMake(230,9999); 
   expectedLabelSize = [specialityObj.name sizeWithFont:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; //iOS 6 and previous. 
   total_height = total_height + expectedLabelSize.height;
}

2) Решение 2

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; // Your Font-style whatever you want to use.
gettingSizeLabel.text = @"YOUR TEXT HERE";
gettingSizeLabel.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(310, 9999); // this width will be as per your requirement

CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

Первое решение - иногда не вернуть правильное значение высоты. так что используйте другое решение. который будет работать отлично.

Второй вариант довольно хорошо работает и работает плавно во всех iOS без условного кода.


1
почему 230, 999? Откуда вы
берете

1
230 может быть любым числом. Он представляет ширину, которую вы хотите для вашего ярлыка. 9999 я бы предпочел заменить на INFINITY или MAXFLOAT.
Флориан Фридрих

Второе решение работает как шарм. Спасибо Нирав.
Джим

1
«[AppHandlers zHandler]» выдает ошибку. «Необъявленные идентификаторы». Как это решить?
Димпл

9

Вот простое решение:

Требования :

CGSize maximumSize = CGSizeMake(widthHere, MAXFLOAT);
UIFont *font = [UIFont systemFontOfSize:sizeHere];

Сейчас, поскольку constrainedToSizeusage:lineBreakMode:использование устарело в iOS 7.0 :

CGSize expectedSize = [stringHere sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];

Теперь использование в большей версии iOS 7.0 будет:

// Let's make an NSAttributedString first
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:stringHere];
//Add LineBreakMode
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
// Add Font
[attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];

//Now let's make the Bounding Rect
CGSize expectedSize = [attributedString boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

7

Ниже приведены два простых метода, которые заменят эти два устаревших метода.

И вот соответствующие ссылки:

Если вы используете NSLineBreakByWordWrapping, вам не нужно указывать NSParagraphStyle, так как это значение по умолчанию: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index. HTML # // apple_ref / ОКК / CLM / NSParagraphStyle / defaultParagraphStyle

Вы должны получить предел размера, чтобы соответствовать результатам устаревших методов. https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/#//apple_ref/occ/instm/NSString/boundingRectWithSize:options:attributes:context :

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font {    
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
}

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
    CGRect textRect = [text boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:@{NSFontAttributeName: font}
                                     context:nil];
    return CGSizeMake(ceilf(textRect.size.width), ceilf(textRect.size.height));
}

6

В большинстве случаев я использовал метод sizeWithFont: constrainedToSize: lineBreakMode: чтобы оценить минимальный размер UILabel для размещения его текста (особенно, когда метка должна быть размещена внутри UITableViewCell) ...

... Если это именно ваша ситуация, вы можете просто использовать метод:

CGSize size = [myLabel textRectForBounds:myLabel.frame limitedToNumberOfLines:mylabel.numberOfLines].size;

Надеюсь, это поможет.


5
В документации Apple говорится, что вы не должны вызывать этот метод напрямую.
Барлоу Такер

По крайней мере, не упоминается в документации по iOS 7 SDK.
Ривера

3
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName: font} context:nil];
CGSize stringSize= new.size;

3
Добро пожаловать в StackOverFlow. Не размещайте тот же ответ снова. Если вам нужно что-то добавить к ответу, оставьте комментарий или отредактируйте ответ.
Ramaraj T

хорошо .. я приму это во внимание в следующий раз. Спасибо за ваш совет.
user3575114

2

[Принятый ответ хорошо работает в категории. Я перезаписываю устаревшие имена методов. Это хорошая идея? Кажется, работает без жалоб в Xcode 6.x]

Это работает, если ваша цель развертывания 7.0 или выше. Категория естьNSString (Util)

NSString + util.h

- (CGSize)sizeWithFont:(UIFont *) font;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;

NSString + Util.m

- (CGSize)sizeWithFont:(UIFont *) font {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    return [self sizeWithAttributes:fontAsAttributes];
}

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    CGRect retVal = [self boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:fontAsAttributes context:nil];
    return retVal.size;
}

0
UIFont *font = [UIFont fontWithName:@"Courier" size:16.0f];

NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;

NSDictionary *attributes = @{ NSFontAttributeName: font,
                    NSParagraphStyleAttributeName: paragraphStyle };

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:attributes
                                 context:nil];

CGSize size = textRect.size;

из двух ответов 1 + 2

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.