2013-11-17 2 views
2

Я использую iOS7.Проблема при попытке изменить динамическую высоту UITextView

Я хочу динамически изменять высоту моего UITextView в соответствии с высотой содержимого. Тем не менее, я нахожусь в iOS7, contentSize - беспорядок. Например, когда я удаляю строку, contentSize не изменится, но я ожидаю, что ее высота уменьшится.

Итак, я пишу следующее

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    // increase a line 
    if ([text isEqualToString:@"\n"]) { 
     _FRAME_SET_H(textView, textView.contentSize.height + 24.0f); 

    // decrease a line 
    } else if (range.length == 1 && [textView.text hasSuffix:@"\n"]) { 
     _FRAME_SET_H(textView, textView.contentSize.height - 24.0f); 

    } else { 
     _FRAME_SET_H(textView, textView.contentSize.height); 
    } 

    return YES; 
} 

Все работает отлично, пока я ввода очень длинный текст:

enter image description here

contentSize не изменится, если текст достаточно долго, чтобы вызвать автоматическое изменение строки!

Может ли кто-нибудь мне помочь?

Что я хочу просто: измените высоту UITextView в соответствии с его содержимым. Тем не менее, я потратил на него более двух дней, но до сих пор не решил.

UITextView в iOS7 является такой ошибкой.


Я попытался выполнить решение Uptown Apps. Ниже приводится мой новый код (немного изменился для моего другого проекта):

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    return YES; 
} 

- (void)textViewDidChange:(UITextView *)textView { 
    CGRect rect = [textView.text 
        boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX) 
        options:NSStringDrawingUsesLineFragmentOrigin 
        attributes:@{NSFontAttributeName: textView.font} 
        context:nil]; 
    _FRAME_SET_H(textView, rect.size.height); 

    _FRAME_SET_H(self, _FRAME_H(textView) + _BLOCK_PADDING * 2); 
} 

Однако проблема остается. На следующем изображении белый прямоугольник является UITextView, а черный фон - его надписью.

Когда я запустить приложение, высота UITextView является 0, и экран выглядит следующим образом: enter image description here

Тогда я типа «А», экран превращается в: enter image description here

Вы видите есть две проблемы: 1) высоты недостаточно. 2) каретка странная!

Тогда я набираю еще немного «а», экран превращается в: enter image description here

Тогда я типа «возврат», чтобы изменить линию, экран превращается в: enter image description here

Да, не меняется! Но я ожидаю, что он увеличит свою высоту, включив новую пустую строку.

Тогда я типа «A», экран не превращается в: enter image description here

Высота увеличивается, но новый текст не отображается, ни в каретку. Я думаю, это также связано с тем, что высоты недостаточно.

Тогда я типа другой 'а', экран превращается в: появляются enter image description here

Letters, но только половина ...

Кстати, когда я использую UILabel, я могу получить правильную высоту текста, используя этот метод !!!! (Т.е. вызова boundingRectWithSize :)

ответ

6

--Edit--

См How do I size a UITextView to its content?

После того, как текст изменился, вы можете вернуться к исходному раствору с помощью contentSize. Я настроил этот код, чтобы использовать maxHeight

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    return YES; 
} 

- (void)textViewDidChange:(UITextView *)textView 
{ 
    CGFloat maxHeight = 312.0f; 
    CGFloat fixedWidth = textView.frame.size.width; 
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)]; 
    CGRect newFrame = textView.frame; 
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), fminf(newSize.height, maxHeight)); 
    textView.frame = newFrame; 
} 

--Original Answer--

Вы пробовали ожидание, пока текст не изменился, а затем использовать методы NSString, чтобы получить размер? Я не тестировал это, но он должен начать работать в правильном направлении.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    return YES; 
} 

- (void)textViewDidChange:(UITextView *)textView{ 

    CGFloat myMaxSize = 568.0f; // Set to max height you would ever want your textView to expand to 

    CGRect frameRect = textView.frame; 
    CGRect rect = [textView.text 
boundingRectWithSize:CGSizeMake(frameRect.size.width, CGFLOAT_MAX) 
      options:NSStringDrawingUsesLineFragmentOrigin 
      attributes:@{NSFontAttributeName: textView.font} 
      context:nil]; 

    CGSize size = rect.size; 
    if (size.height > myMaxSize) { 
     size.height = myMaxSize; 
    } 

    frameRect.size = size; 
    [textView setFrame:frameRect]; 

} 
+0

Я обновил свое сообщение, пожалуйста, обратитесь к нему. – HanXu

+0

Я думаю, что у вас может быть ошибка в вашей функции _FRAME_SET_H. Вы пытаетесь расширить текст вверх (нравится приложение «Сообщения»)? Мой код этого не делает, но может быть адаптирован для этого. –

+0

Вау, я должен был это увидеть раньше. После того, как вы измените текст, вы можете использовать размер содержимого, как вы хотели. См. Http://stackoverflow.com/questions/50467/how-do-i-size-a-uitextview-to-its-content. Единственное, что вам нужно учитывать, - это максимальная высота и прокрутка представления, когда вы нажмите максимальную высоту и введите символ новой строки (возврат), но не ввели новый текст. –

0

Вы можете получить правильную высоту текста с помощью этой функции:

CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:13.0f] constrainedToSize:CGSizeMake(textView.width, 20000) lineBreakMode: NSLineBreakByWordWrapping]; 

float text_height = textSize.height; 

Эта функция ограничивает текст в ширину вашего TextView. Таким образом, в соответствии с шириной, он возвращает высоту текста в этом пространстве.

Дайте мне знать!

+0

'sizeWithFont: constrainedToSize: lineBreakMode:' устарел от iOS7. Теперь вы должны использовать 'boundingRectWithSize: options: attributes: context:' за мой ответ. –

0

Вы можете изменить высоту представления текста динамически, используя:

[textView sizeToFit]; 

Но проблема в том, что, если содержание внутри вида текста слишком мало, он будет изменять размер меньше исходного размера , Вот лучшее решение для этого:

- (void)textViewDidChange:(UITextView *)textView{ 
    CGRect frameForTextView=textView.frame; 
    [textView sizeToFit]; 
    if (textView.frame.size.height < frameForTextView.size.height) { 
     textView.frame=frameForComments; 
    } 
    else 
    { 
     //Do other UI adjustment here when height of textView increased than default size  
    } 
} 
Смежные вопросы