Как рассчитать высоту NSAttributedString без замораживания основного потока

Я работаю над приложением, которое отображает сообщения, содержащие текст разной длины. Когда я получаю данные через запрос сервера, я применяю форматирование к NSAttributedString, вычисляю высоту текста для определенной ширины, а затем сохраняю это значение, когда tableView вызовет heightForRowAtIndexPath: позже.

Для каждого нового поста я вызываю этот метод:

- (CGFloat)calculateTextViewHeight:(NSString *)string
{
    NSAttributedString *bodyText = [self formatString:string];
    UITextView *tempTextField = [[UITextView alloc] init];
    tempTextField.attributedText = bodyText;
    return [tempTextField sizeThatFits:CGSizeMake(cellWidth, FLT_MAX)].height;
}

Это прекрасно работает. Однако, когда я перебираю от 50 до 200 сообщений за раз, tableView зависает. Насколько я понимаю, sizeThatFits: это метод UIKit и поэтому должен выполняться в основном потоке.

Есть ли способ вычислить высоту NSAttributedString без зависания основного потока. Или, может быть, есть способ запустить sizeThatFits: в фоновом потоке?


person Shawn Throop    schedule 01.01.2014    source источник


Ответы (1)


Конечно, вам не нужно создавать временное текстовое поле?

- (CGFloat)calculateTextViewHeight:(NSString *)string
{
  NSAttributedString *bodyText = [self formatString:string];
  CGRect rect = [bodyText boundingRectWithSize:CGSizeMake(width, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
  return CGRectGetHeight(rect);
}

Настройте параметры опции в соответствии с вашими потребностями,

Примечание: это было закодировано в браузере

person Oliver Atkinson    schedule 01.01.2014
comment
Я обнаружил, что этот метод не так надежен, как метод Шона при получении точных чисел. - person Hot Licks; 02.01.2014
comment
Ого, такое улучшение! Точность не проверял, но мне кажется, что работает. Я использовал UITextView, потому что в своем пользовательском TableViewCell я использую UITextView, поэтому я могу легко отслеживать прикосновения. Если я использую UILabel, он работает как шарм. Спасибо за ваш быстрый ответ! - person Shawn Throop; 02.01.2014
comment
Более того, в документах говорится, что вы можете вызывать методы NSAttributedString из фонового потока (если вы не пытаетесь совместно использовать объекты NSStringDrawingContext между потоками). - person Duncan C; 02.01.2014
comment
просто создайте UItextView один раз как переменную экземпляра. Затем всегда использовал это, чтобы сделать sizeThatFit: calc. - person John; 02.01.2014
comment
@DuncanC Я новичок в Objective-C, знаете ли вы какие-либо ресурсы, которые могли бы познакомить меня с получением вещей в фоновом потоке? - person Shawn Throop; 02.01.2014
comment
@ShawnThroop попробуйте это - stackoverflow. ком/вопросы/15199342/ - person Oliver Atkinson; 03.01.2014
comment
@DuncanC, что вы имеете в виду, говоря, что в документах говорится, что вы можете вызывать методы NSAttributedString из фонового потока? developer.apple.com/library/prerelease/ ios/documentation/UIKit/ на этой странице говорится, что методы, описанные в этом расширении класса, должны использоваться из основного потока вашего приложения. - person storoj; 20.01.2016