BoundingRectWithSize не поддерживает перенос слов

Я создаю UITextView, добавляю к нему текст и помещаю его в представление (с контейнером)

UITextView *lyricView = [[UITextView alloc] initWithFrame:screen];
lyricView.text = [NSString stringWithFormat:@"\n\n%@\n\n\n\n\n\n", lyrics];
[container addSubview:lyricView];
[self.view addSubview:container];

Затем я получаю его размер для использования с кнопкой и добавляю его в UITextView

CGRect size = [lyrics boundingRectWithSize:CGSizeMake(lyricView.frame.size.width, MAXFLOAT)
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:[lyricView font]}
                                 context:nil];
UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[doneButton setFrame:CGRectMake(56, size.size.height + 55, 208, 44)];
[doneButton setTitle:@"Done" forState:UIControlStateNormal];
[lyricView addSubview:doneButton];

Это работает в большинстве случаев. Это будет уважать \n разрывы строк (например, я добавил в свой stringWithFormat), но он не будет уважать переносы слов, автоматически добавляемые текстовым представлением. Поэтому, если lyrics имеет строку, которая не помещается на экране, UITextView будет ее обертывать (как и предполагалось), но size теперь немного короче, чем это должно быть, потому что это не соответствовало переносу текстового представления.

Ответ 1

Сделал еще несколько исследований и в итоге нашел этот.

CGSize textSize = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, FLT_MAX)];
CGFloat textHeight = textSize.height;

Надеюсь, это поможет кому-то там!

Ответ 2

Вы можете сказать boundingRectWithSize обработать строку в режиме обертывания слов. Вы должны добавить атрибут NSParagraphStyle к параметру атрибутов, а его lineBreakMode - NSLineBreakByWordWrapping. Итак:

NSMutableDictionary *attr = [NSMutableDictionary dictionary];     
// ...whatever other attributes you need...
NSMutableParagraphStyle *paraStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paraStyle.lineBreakMode = NSLineBreakByWordWrapping;
[attr setObject:paraStyle forKey:NSParagraphStyleAttributeName];

затем используйте attr в качестве аргумента атрибутов для boundingRectWithSize.

Вы можете легко расширить/обобщить эту технику для чтения других атрибутов, включая существующие атрибуты стиля абзаца из любого источника, имеющего смысл.

Ответ 3

Должен использовать (NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) для параметра options.