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