Заміна застарілого -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 ....]"


13
А де ви згадуєте NSLineBreakByWordWrapping? Wherre це пішло?
user4951

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

1
@ffried у моєму випадку додавання абзацуStyle з розривом рядків, відмінним від 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? Звідки ви берете номер>
user4951

1
230 може бути будь-яким числом. Він представляє потрібну вам ширину для вашої етикетки. Я б 9999 замінив на INFINITY або MAXFLOAT.
Флоріан Фрідріх

Друге рішення - це як шарм. Дякую Нірав.
Джим

1
"[AppHandlers zHandler]" видає помилку. "Недекларовані ідентифікатори". Як це вирішити?
Dimple

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 / occ / 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 йдеться про те, що не слід закликати цей метод безпосередньо.
Barlow Tucker

Не згадується в документації SDK для iOS 7.
Рівера

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. Не надсилайте знову таку ж відповідь. Якщо вам потрібно додати щось до відповіді, напишіть коментар або виконайте редагування відповіді.
Рамарай Т

ОК .. Я буду враховувати це наступним разом. Дякую за пораду.
користувач3575114

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.