2013-09-26 2 views
73

Я портирую одно из приложений от iOS 6.1 до iOS 7. Я использую макет, где есть UITextView с шириной исправления, но высота основана на его содержимом. Для проверки iOS 6.1 содержимого contentize.height и установки его в качестве высоты фрейма текста было достаточно, но оно не работает на iOS 7.iOS7 UITextView contentize.height alternative

Как я могу создать UITextView с фиксированной шириной, но динамическая высота на основе текст, который он показывает?

ПРИМЕЧАНИЕ: Я создаю эти представления из кода, а не с Interface Builder.

ответ

177

С помощью этого следующего кода, вы можете изменить высоту вашего UITextView в зависимости от фиксированной ширины (он работает на прошивке 7 и предыдущую версию):

- (CGFloat)textViewHeightForAttributedText:(NSAttributedString *)text andWidth:(CGFloat)width 
{ 
    UITextView *textView = [[UITextView alloc] init]; 
    [textView setAttributedText:text]; 
    CGSize size = [textView sizeThatFits:CGSizeMake(width, FLT_MAX)]; 
    return size.height; 
} 

С помощью этой функции вы будете принимать NSAttributedString и фиксированную ширину, чтобы вернуть требуемую высоту.

Если вы хотите, чтобы вычислить кадр из текста с определенным шрифтом вам, нужно использовать следующий код:

- (CGSize)text:(NSString *)text sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size 
{ 
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) 
    { 
     CGRect frame = [text boundingRectWithSize:size 
              options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) 
             attributes:@{NSFontAttributeName:font} 
              context:nil]; 
     return frame.size; 
    } 
    else 
    { 
     return [text sizeWithFont:font constrainedToSize:size]; 
    } 
} 

Вы можете добавить, что SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO на файл prefix.pch в проекте как:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 

Вы также можете заменить предыдущий тест SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) по:

if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])‌ 
+0

я могу только дайте его вам через 24 часа. будьте терпеливы, это ваше :) –

+16

Возможно, вам следует ссылаться на ответы, на которые вы их взяли? http://stackoverflow.com/questions/18368567/uitableviewcell-with-uitextview-height-in-ios-7 – Anderscc

+0

@ Джордан Монтель, для другого вопроса, если у меня фиксированная ширина и высота, как я могу найти лучший размер шрифта для назначенной строки? У меня аналогичная проблема на iOS7 (на iOS6, я могу это сделать) – Jacky

2

Есть проще решение, с помощью этого метода:

+(void)adjustTextViewHeightToContent:(UITextView *)textView; 
{ 
    if([[UIDevice currentDevice].systemVersion floatValue] >= 7.0f){ 
     textView.height = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height+2*fabs(textView.contentInset.top); 
    }else{ 
     textView.height = textView.contentSize.height; 
    } 
} 

UPD: работа только для отображения текста (IsEditable = NO)

+0

Кажется, что ваше утверждение не работает. Когда textview goto второй метод 'usedRectForTextContainer' возвращает ту же высоту. –

+0

О, может быть, я просто использую его для отображения текста – HotJard

3

Мое окончательное решение основано на HotJard, но включает в себя как верхнюю и нижние вставки текстового контейнера вместо использования 2 * fabs (textView.contentInset.сверху):

- (CGFloat)textViewHeight:(UITextView *)textView 
{ 
    return ceilf([textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height + 
       textView.textContainerInset.top + 
       textView.textContainerInset.bottom); 
} 
42

Это работало для меня iOS6 и 7:

CGSize textViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)]; 
    self.myTextView.height = textViewSize.height; 
+0

Привет, Да, его укусы для меня ... Я использую «txtviewHeight.frame.size.height» вместо «txtviewHeight.contentSize.height» – Mani

+0

oh .. super легко! – BufferStack

+0

Почему я получаю свойство высоты не найден на объекте типа «UITextView»? – Hexark

15

Используйте эту маленькую функцию

-(CGSize) getContentSize:(UITextView*) myTextView{ 
    return [myTextView sizeThatFits:CGSizeMake(myTextView.frame.size.width, FLT_MAX)]; 
} 
+0

Работает в iOS6 и iOS7 для меня. Благодаря! –

20

В iOS7, UITextView использует NSLayoutManager макет текста:

// If YES, then the layout manager may perform glyph generation and layout for a given portion of the text, without having glyphs or layout for preceding portions. The default is NO. Turning this setting on will significantly alter which portions of the text will have glyph generation or layout performed when a given generation-causing method is invoked. It also gives significant performance benefits, especially for large documents. 
@property(NS_NONATOMIC_IOSONLY) BOOL allowsNonContiguousLayout; 

disable allowsNonContiguousLayout исправить contentSize:

textView.layoutManager.allowsNonContiguousLayout = NO; 
+6

Ваш ответ не соответствует вопросу, но подходит для моей проблемы. Поэтому я проголосую :) –

+0

Это не фиксирует размер контента для меня. Прокрутка отключена. – Dvole

+0

Этот фрагмент кода решил мою проблему, но что означает метод генерации, который вы прокомментируете? –

1
_textView.textContainerInset = UIEdgeInsetsZero; 
    _textView.textContainer.lineFragmentPadding = 0; 

Просто не забывайте о lineFragmentPadding

0

простое решение - textView.isScrollEnabled = false отлично работает, когда внутри другой вид прокрутки, или Tableview ячейка с UITableViewAutomaticDimension

Смежные вопросы