У меня есть вид, который выложен полностью с использованием автоматического макета программного обеспечения. У меня есть UITextView в середине представления с элементами выше и ниже. Все работает нормально, но я хочу иметь возможность расширять UITextView по мере добавления текста. Это должно подтолкнуть все ниже под ним, поскольку это расширяется.
Я знаю, как это сделать «пружинами и распорками», но есть ли способ автоматической компоновки? Единственный способ, о котором я могу думать, - это удаление и повторное добавление ограничения каждый раз, когда оно должно расти.
Ответы:
Представлению, содержащему UITextView, будет назначен его размер с
setBounds
помощью AutoLayout. Итак, это то, что я сделал. В суперпредставлении изначально установлены все остальные ограничения, как и должно быть, и в конце я установил одно специальное ограничение для высоты UITextView и сохранил его в переменной экземпляра.В
setBounds
методе я затем изменил значение константы.источник
textViewDidChange
этим следует сэкономить немного времени и писать код…textViewDidChange:
не будет вызываться при программном добавлении текста в UITextView.Сводка: отключите прокрутку вашего текстового представления и не ограничивайте его высоту.
Чтобы сделать это программно, поместите следующий код в
viewDidLoad
:Чтобы сделать это в Интерфейсном Разработчике, выберите текстовое представление, снимите отметку с прокруткой, Включенной в Инспекторе Атрибутов, и добавьте ограничения вручную.
Примечание. Если у вас есть другие представления выше или ниже вашего текстового представления, рассмотрите возможность использования
UIStackView
их всех.источник
intrinsicContentSize
так- (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; if (self.text.length == 0) { size.height = UIViewNoIntrinsicMetric; } return size; }
. Скажи мне, если это работает для тебя. Сам не проверял.Вот решение для людей, которые предпочитают делать все это с помощью автоматического макета:
По размеру инспектор:
Установите приоритет сопротивления сжатию контента по вертикали на 1000.
Понизьте приоритет высоты ограничения, нажав «Изменить» в Ограничениях. Просто сделайте это меньше 1000.
Инспектор атрибутов:
источник
UITextView не предоставляет intrinsicContentSize, поэтому вам нужно создать его подкласс и предоставить его. Чтобы он автоматически увеличивался, сделайте недействительным intrinsicContentSize в layoutSubviews. Если вы используете что-то кроме стандартного contentInset (который я не рекомендую), вам может потребоваться настроить вычисление intrinsicContentSize.
источник
setScrollEnabled:
всегда устанавливать егоNO
вы получите бесконечный цикл для постоянно растущего внутреннего размера контента.[textView sizeToFit]
вtextViewDidChange:
делегате обратного вызова для автоматического макета расти или уменьшить TextView (и пересчитать все зависимые ограничения) после каждого нажатия клавиши.-(void)layoutSubviews
и обернуть все код в-(CGSize)intrinsicContentSize
сversion >= 7.0f && version < 7.1f
+else return [super intrinsicContentSize];
Вы можете сделать это через раскадровку, просто отключив "Scrolling Enabled" :)
источник
Я обнаружил, что в ситуациях, когда вам все еще может понадобиться, isScrollEnabled имеет значение true, чтобы разрешить разумное взаимодействие с пользовательским интерфейсом. Простой случай для этого - когда вы хотите разрешить автоматическое расширение текстового представления, но при этом ограничить его максимальную высоту до чего-то разумного в UITableView.
Вот подкласс UITextView, который я придумал, который позволяет автоматическое расширение с автоматическим макетом, но вы все равно можете ограничиться максимальной высотой и который будет управлять прокруткой вида в зависимости от высоты. По умолчанию представление будет расширяться до бесконечности, если вы настроили ограничения таким образом.
В качестве бонуса есть поддержка включения текста-заполнителя, похожего на UILabel.
источник
Вы также можете сделать это без подклассов
UITextView
. Взгляните на мой ответ на вопрос «Как изменить размер UITextView для его содержимого на iOS 7?».Используйте значение этого выражения:
обновить
constant
изtextView
высоты «SUILayoutConstraint
.источник
Важно отметить:
Поскольку UITextView является подклассом UIScrollView, он подчиняется автоматически свойству AdjustsScrollViewInsets UIViewController.
Если вы настраиваете макет, а TextView является первым подпредставлением в иерархии UIViewControllers, его contentInsets будут изменены, если автоматически установлено значение trueAdjustsScrollViewInsets, иногда вызывающее непредвиденное поведение в автоматическом макете.
Так что, если у вас есть проблемы с автоматическим макетом и текстовыми представлениями, попробуйте установить
automaticallyAdjustsScrollViewInsets = false
на контроллере представления или переместить textView вперед в иерархии.источник
Это более важный комментарий
Ключ к пониманию того, почему ответ Витаминной воды работает, три вещи:
contentOffset
, скорее всего, ничего, кроме:Для получения дополнительной информации см. Objc scrollview и понимание scrollview.
Комбинируя все три, вы легко поймете, что вам нужно позволить внутреннему контенту textView sizeView работать в соответствии с ограничениями AutoLayout textView для управления логикой. Это почти так, как будто вы textView работает как UILabel
Чтобы это произошло, вам нужно отключить прокрутку, что в основном означает размер scrollView, размер contentSize и, в случае добавления containerView, тогда размер containerView будет одинаковым. Когда они одинаковы, у вас нет прокрутки. И ты бы сделал . Наличие означает, что вы не прокручивали вниз. Даже 1 балл вниз! В результате textView будет растянут.
0
contentOffset
0
contentOffSet
Это также ничего не стоит, что означает, что границы и рамка scrollView идентичны. Если вы прокрутите вниз на 5 пунктов, то ваш contentOffset будет , а ваш будет равен
0
contentOffset
5
scrollView.bounds.origin.y - scrollView.frame.origin.y
5
источник
Решение Plug and Play - Xcode 9
Autolayout так же , как
UILabel
, с обнаружением связи , выделение текста , редактирование и прокруткой изUITextView
.Автоматически обрабатывает
Многие из этих ответов дали мне 90%, но ни один не был дурака.
Загляните в этот
UITextView
подкласс, и все хорошо.источник
Ответ Витаминной воды работает на меня.
Если во время редактирования текст вашего текстового представления подпрыгивает вверх и вниз, после настройки
[textView setScrollEnabled:NO];
установитеSize Inspector > Scroll View > Content Insets > Never
.Надеюсь, поможет.
источник
Поместите скрытую UILabel под вашим textview. Линии метки = 0. Установите ограничения UITextView равными UILabel (centerX, centerY, ширина, высота). Работает, даже если вы оставите прокрутку textView.
источник
Кстати, я построил расширяющийся UITextView, используя подкласс и переопределяя внутренний размер контента. Я обнаружил ошибку в UITextView, которую вы, возможно, захотите исследовать в своей собственной реализации. Вот проблема:
Раскрывающееся представление текста будет уменьшаться, чтобы вместить растущий текст, если вы набираете по одной букве за раз. Но если вы вставите в него кучу текста, он не будет уменьшаться, но текст будет прокручиваться вверх, а текст сверху не будет виден.
Решение: переопределить setBounds: в вашем подклассе. По какой-то неизвестной причине, из-за вставки значение bounds.origin.y было ненулевым (33 в каждом случае, который я видел). Поэтому я переопределил setBounds: всегда устанавливать bounds.origin.y на ноль. Исправлена проблема.
источник
Вот быстрое решение:
Эта проблема может возникнуть, если вы установили для свойства clipsToBounds значение false для вашего текстового представления. Если вы просто удалите его, проблема исчезнет.
источник
источник