'sizeWithFont: constrainedToSize: lineBreakMode:' устарела:

Получил вышеуказанную ошибку: в Visual Studio 2013 для исправления: в пакете mamnager Execute: Install-package newtonsoft.json Это добавит новую строку в packages.config <package id="Newtonsoft.Json" version="6.0.5" targetFramework="net45" /> Удаляет предыдущую строку, которая может указывать на предыдущую версию на packages.config. Удалите каталог старой версии в каталоге packagers. Удалите ссылку NewtonSoft.Json и прочитайте ее, указав на последнюю версию. У корневого webconfig будет следующее <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />, как только все будет сделано. Закройте и откройте визуальную студию. Это должно исправить это. У меня была такая же ошибка при установке PM> install-package durandal.starterkit. Я использовал вышеупомянутый метод для исправления.

29
задан iSrini 20 September 2013 в 17:10
поделиться

6 ответов

Я бы не стал маскировать предупреждение об устаревшей функции. Они осудили это по причине. Я считаю, что эта функция устарела, потому что эта серия функций 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);
64
ответ дан Mr. T 20 September 2013 в 17:10
поделиться

Если вы хотите, чтобы он был совместим как с 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 случай, может быть, вам нужно сделать некоторые изменения в зависимости от того, что вы хотите, чтобы это было. ;)

44
ответ дан Kjuly 20 September 2013 в 17:10
поделиться

Вы можете использовать:

UIFont *font = [UIFont boldSystemFontOfSize:16];

CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300)
    options:NSStringDrawingUsesFontLeading 
    attributes:@{NSFontAttributeName: font} 
    context:nil];

CGSize stringSize= new.size;
2
ответ дан Andrew Stubbs 20 September 2013 в 17:10
поделиться

Проблема boundingRectWithSize: options: attribute: context заключается в том, что он неправильно вычисляет высоту, если строка содержит «\ 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));
1
ответ дан EckhardN 20 September 2013 в 17:10
поделиться

Для 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;
10
ответ дан Kevin 20 September 2013 в 17:10
поделиться

Если вы ориентируетесь на iOS 6.0+, вы все равно можете использовать sizeWithFont:constrainedToSize:lineBreakMode:. Просто убедитесь, что для вашего проекта iOS Deployment Target установлено значение 6.0, и компилятор не выдаст вам эти предупреждения.

(Вы можете найти это, нажав на синюю вкладку проекта (обычно вверху слева, панель навигатора проекта) в разделе «информация»).

Если вы ориентируетесь только на iOS 7.0+, вам следует использовать новый метод boundingRectWithSize:options:attributes:context.

Вы можете найти документы Apple по этому новому методу здесь.

1
ответ дан JRG-Developer 20 September 2013 в 17:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: