Текст UITextView становится невидимым после достижения высоты 8192.0

У меня есть прокручиваемый UITextView встроенный в UIScrollView и динамически добавляющий текст в UITextView. UIScrollView отрегулируйте его contentSize соответственно на основе кадра TextView. Однако, как только UITextView превысит высоту 8192, текст станет невидимым (но все же там, потому что вы можете использовать увеличительное стекло, чтобы выделить текст и даже увидеть части текста через увеличительное стекло).

  CGRect textviewFrame = self.TextView.frame;
  textviewFrame.size.height = [self textViewHeightForAttributedText:self.TextView.attributedText andWidth:320.0];
  self.TextView.frame = textviewFrame;
  self.ScrollView.contentSize = self.TextView.frame.size;

Функция помощника для размера UITextView соответственно:

- (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;
}

Не понял, что была та же самая точная проблема, которая была не решена здесь, пока я не проверил ее явно, заставив максимальный размер 8193 и возникла проблема (в то время как максимальный размер 8192 по-прежнему отображал текст правильно). Кто-нибудь сталкивается с этой проблемой раньше и знает о работе? Благодаря

Ответ 1

Недавно я столкнулся с этой проблемой и разработал эффективный способ ее решения. Хотя это похоже на ошибку iOS IMHO, на самом деле это не так... есть практические ограничения для размеров CALayer, а также рисование 8К высокой длины текста занимает много времени. Гораздо лучше сделать то, что планировал Apple, и отображать только немного текста, видимого... что UITextView расширяет UIScrollView в конце концов.

Проблема в том, что UITextView не очень легко интегрируется с другими битами пользовательского интерфейса. В моем случае я работаю над новостным приложением, в котором один и тот же UITextView используется для рендеринга статьи, плюс некоторые отдельные UI (заголовки и кнопки и т.д.) Выше и ниже, все они размещены в одном прокручиваемом контейнере.

Решение, которое я нашел, состоит в том, чтобы разбить UITextView на два представления... выделенный контейнер UITextView, чей фрейм - полный размер текста (т.е. тот же размер вашего UITextView contentSize) и который является надзором вашего UITextView. Ваш дочерний кадр UITextView должен быть установлен на границы внешнего прокручиваемого контейнера.

Затем все, что вам нужно сделать, это использовать наблюдение за ключевыми значениями для контроля над свойством contentOffset внешнего вида прокручиваемого контейнера (в моем случае это UICollectionView). Когда изменяется его contentOffset, вы обновляете (1) contentOffset вашего UITextView и (2) свойство преобразования слоя UITextView. Обновляя это свойство преобразования, UITextView фиксируется, чтобы заполнить видимую в данный момент часть его супервизора. Но поскольку вы также обновляете UITextView contentOffset, этот обман совершенно невидим для пользователя... он выглядит и ведет себя так, как будто UITextView просто очень большой.

Ответ 2

Здесь полнофункциональное решение для всех, кто захочет!

** Предполагая, что размер вашего контента не будет превышать пределы двух текстовых представлений **

Это решение работает, добавляя к вашему представлению два UITextViews и разбивая текст между ними. Это выглядит сложным, но на самом деле это очень просто! Я только что написал очень подробное описание:)

Шаг 1 - добавьте два представления UITextViews к вашему представлению:

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

r4R3B.png

Установите ограничения на представления так, чтобы они были привязаны друг к другу сверху и снизу и окружающие края контейнера со всех сторон, включая требуемое заполнение. i.e. привязать первое текстовое представление к контейнеру сверху, слева и справа и ко второму текстовому виду снизу. Свяжите второй текстовый вид с контейнером снизу, слева и справа и с первым текстовым видом сверху. Это гарантирует, что они будут растягиваться соответствующим образом при настройке содержимого.

hJMwO.pngnwbfU.png

Не устанавливайте никаких ограничений на высоту представлений или если вы должны (чтобы избежать предупреждений от инспектора ограничений), установите высоту одного из видов, которые будут >= 20, или немного аналогичного числа.

Отключить прокрутку, перескакивание и прокрутку индикаторов для ваших текстовых просмотров. Это решение полагается на представления, являющиеся фиксированной высотой без прокрутки, поэтому, если вы хотите, чтобы ваш контент прокручивался, вы должны использовать UIScrollView или UITableViewCell в качестве контейнера.

Tk4Uc.png

Создайте выходные данные для двух новых текстовых представлений в файле контроллера вашего вида, называя их чем-то вроде textView1 и textView2.

Шаг 2 - Установите значение textContainerInsets в ноль:

Установите свойство textContainerInset в обоих текстовых представлениях равным нулю, либо используя атрибуты времени выполнения, определенные пользователем:

ZriFm.png

или код:

self.textView1.textContainerInset = UIEdgeInsetsZero;
self.textView2.textContainerInset = UIEdgeInsetsZero;

Это обеспечит отсутствие видимого пространства между двумя представлениями при установке содержимого и не должно влиять на другое расстояние вокруг ваших представлений.

Шаг 3 - Разделите свой контент, установите его и обновите высоты просмотров:

Просто скопируйте следующий код в файл контроллера вида (viewDidLoad) и установите для переменной contentString свой контент.

/* Content is split across two UITextViews to avoid max drawing height */

NSString *contentString = @"Some very long piece of text...";

// Set text
NSArray *components = [contentString componentsSeparatedByString:@"\n"];
NSInteger halfLength = [components count] / 2;
NSArray *firstHalf = [components subarrayWithRange:NSMakeRange(0, halfLength)];
NSArray *secondHalf = [components subarrayWithRange:NSMakeRange(halfLength, [components count] - halfLength)];
NSString *contentString1 = [firstHalf componentsJoinedByString:@"\n"];
NSString *contentString2 = [secondHalf componentsJoinedByString:@"\n"];
self.textView1.text = contentString1;
self.textView2.text = contentString2;

// Set text view heights
CGFloat fixedWidth1 = self.textView1.frame.size.width;
CGFloat fixedWidth2 = self.textView2.frame.size.width;
CGSize newSize1 = [self.textView1 sizeThatFits:CGSizeMake(fixedWidth1, CGFLOAT_MAX)];
CGSize newSize2 = [self.textView2 sizeThatFits:CGSizeMake(fixedWidth2, CGFLOAT_MAX)];
CGRect newFrame1 = self.textView1.frame;
CGRect newFrame2 = self.textView2.frame;
newFrame1.size = CGSizeMake(fmaxf(newSize1.width, fixedWidth1), MIN(newSize1.height, 8192));
newFrame2.size = CGSizeMake(fmaxf(newSize2.width, fixedWidth2), MIN(newSize2.height, 8192));
self.textView1.frame = newFrame1;
self.textView2.frame = newFrame2;

Этот код разбивает ContentString примерно посередине, ища ближайшую новую строку. Если вы хотите разделить свой контент на другой символ, просто измените все вхождения \n выше на все, что вы хотели бы разбить.

Шаг 4 - Установите высоту просмотра контейнера:

Настройте представление контейнера (scrollView, tableViewCell, любое другое) на высоту ваших двух текстовых представлений плюс любое дополнительное пространство, которое вы установили выше и ниже.

CGRect viewFrame = self.myView.frame;
viewFrame.size.height = MIN(self.textView1.frame.size.height, 8192) + MIN(self.textView2.frame.size.height, 8192) + kTextViewContainerPadding;
[self.myView setFrame:viewFrame];

(В моем коде kTextViewContainerPadding - это макрос, который я установил в сумме пробела выше и ниже моих двух текстовых представлений в своем контейнере).

Что это! Удачи.

Ответ 3

Попробуйте включить прокрутку для scrollView. Сохраняйте высоту textView> height содержимого, чтобы в действительности не было прокрутки, но scrollEnabled должно быть = YES

Это решило проблему для меня.

Ответ 4

Привет, я думаю, не поздно ответить. У меня такая же проблема, как и вы. Это мое решение:

textView.scrollEnabled = YES;    
contentTextView.attributedText = finalAttrString;
// contentTextView.text = [attrString string];
contentTextView.font = kFont(contentTextFS + [valueOfStepper intValue]);

[contentTextView sizeToFit];
contentTextView.height += 1;//This is the key code
//contentTextView.height = 8192.0f

Им я решил проблему, и я могу изменить размер dynamic.Successfull на iOS 8