'sizeWithFont: constrainedToSize: lineBreakMode:' устарел:
Преобразование проекта с iOS5.0 в iOS7/iOS6 на Xcode 5. В приведенном ниже коде дается предупреждение о времени компиляции:
'sizeWithFont: constrainedToSize: lineBreakMode:' устарел: сначала устарел в ios 7.0 - Use - boundingRectWithSize: options: attribiutes: context
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
self.lblHidden.frame = CGRectMake(58, 228, 945, 9999);
self.lblHidden.text = detailShareObj.pDesc;
CGSize size = [detailShareObj.pDesc sizeWithFont:self.lblHidden.font constrainedToSize:self.lblHidden.frame.size lineBreakMode:NSLineBreakByWordWrapping];
return 228.0+size.height+20;
}
else if (indexPath.section == 1)
{
NSString *tempPointStr = (self.shortDescArray)[indexPath.row];
self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
self.lblHidden.text = tempPointStr;
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
return 50.0f;
}
Я попробовал некоторое предложение в другом месте, но ничего не спасает, если кто-то может помочь, если внести исправления, требуемые в коде, будет с благодарностью.
Ответы
Ответ 1
Я бы не просто маскировал предупреждение устаревшей функции. Они не одобряли это по какой-то причине. Я считаю, что функция была устаревшей, потому что эта серия функций NSString + UIKit была основана на библиотеке UIStringDrawing, которая не была потокобезопасной. Если вы попытались запустить их не в основном потоке (как и любая другая функция UIKit), вы получите непредсказуемое поведение. В частности, если вы запускаете функцию на нескольких потоках одновременно, это, вероятно, приведет к краху вашего приложения. Вот почему в iOS 6 они внедрили метод boundingRectWithSize:...
для NSAttributedStrings. Это было построено поверх библиотек NSStringDrawing и является потокобезопасным.
Если вы посмотрите на новую функцию NSString boundingRectWithSize:...
, она запрашивает массив атрибутов таким же образом, как и NSAttributeString. Если бы мне пришлось догадаться, эта новая функция NSString в iOS 7 является просто оболочкой для функции NSAttributeString от iOS 6.
В этой заметке, если вы поддерживали только iOS 6 и iOS 7, я бы определенно изменил все ваши NSString sizeWithFont:...
на NSAttributeString boundingRectWithSize
. Это сэкономит вам много головной боли, если у вас будет странный многопоточный угловой футляр! Вот как я преобразовал NSString sizeWithFont:constrainedToSize:
:
Раньше:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];
Можно заменить на:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:text
attributes:@
{
NSFontAttributeName: font
}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
Обратите внимание, что в документации упоминается:
В iOS 7 и более поздних версиях этот метод возвращает дробные размеры (в размере компонент возвращаемого CGRect); использовать возвращаемый размер по размеру просмотров, вы должны использовать, чтобы повысить его значение до ближайшего более высокого целого используя функцию ceil.
Чтобы вытащить вычисленную высоту или ширину, которые будут использоваться для определения размеров, я бы использовал:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
Ответ 2
Если вы хотите, чтобы он был совместим как с iOS7, так и с версиями ниже, попробуйте этот (с ARC):
CGSize size;
if ([tempPointStr respondsToSelector:
@selector(boundingRectWithSize:options:attributes:context:)])
{
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary * attributes = @{NSFontAttributeName : self.lblHidden.font,
NSParagraphStyleAttributeName : paragraphStyle};
size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
options:NSStringDrawingUsesFontLeading
|NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
#pragma clang diagnostic pop
}
Примечание. Это просто пример для вашего случая else-if
, возможно, вам нужно сделать некоторые изменения в зависимости от того, кем вы хотите.;)
Ответ 3
Для iOS7 замените:
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
С
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; //set the line break mode
NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:self.lblHidden.font, NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
CGSize size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
attributes:attrDict context:nil].size;
Ответ 4
Вы можете использовать:
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300)
options:NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName: font}
context:nil];
CGSize stringSize= new.size;
Ответ 5
Если вы ориентируетесь на iOS 6.0+, вы все равно можете использовать sizeWithFont:constrainedToSize:lineBreakMode:
. Просто убедитесь, что для вашего проекта iOS Deployment Target
установлено значение 6.0, и компилятор не даст вам этих предупреждений.
(Вы можете найти это, щелкнув вкладку синего проекта (обычно вверху слева, панель навигации проекта) в разделе "информация" ).
Если вы ориентируетесь только на iOS 7.0+, вы должны использовать новый метод boundingRectWithSize:options:attributes:context
.
Вы можете найти документы Apple по этому новому методу.
Ответ 6
ОграничивающийRectWithSize: options: attributes: контекст имеет проблему, что он не правильно вычисляет высоту, если строка содержит "\n" (разрывы строк). Поэтому этот код вычисляет размер для каждой строки отдельно для заданной ширины (inWidth):
NSArray *brokenByLines=[string componentsSeparatedByString:@"\n"];
CGFloat height=0.0;
CGFloat maxWidth=0.0;
for (NSString* actString in brokenByLines) {
CGRect tSize=[actString boundingRectWithSize:CGSizeMake(inWidth, 600) options:(NSStringDrawingUsesLineFragmentOrigin | NSLineBreakByWordWrapping) attributes:@{NSFontAttributeName: inFont} context:nil];
if (maxWidth<tSize.size.width) {
maxWidth=tSize.size.width;
}
height+=tSize.size.height;
}
CGSize size= CGSizeMake(ceil(maxWidth), ceil(height));