Как настроить высоту textview для его содержимого в SWIFT?
в моем контроллере просмотра у меня есть UITextView. Этот textview заполняется строкой. Строка может быть короткой или длинной. В зависимости от длины строки высота textview должна регулироваться. Я использую раскадровки и макет авто.
у меня есть некоторые проблемы с высотой textview.
иногда высота идеально настраивается на текст. Иногда, нет, текст обрезается на первой линии. Ниже текстовое представление желтого цвета. синий-это containerview внутри scrollview. Фиолетовый-это место для фотографии.
тексты из моей основной базы данных, они являются строковыми атрибутами.
Между экраном 1 и 2, единственное, что изменилось-это строка.
Если я печатаю строки в консоли, у меня есть правильные тексты:
my amazing new title
Another funny title for demo
ограничения моего textview:
Я не понимаю, почему у меня 2 разных дисплеи.
редактировать
я попробовал совет @Nate, в viewDidLoad, я добавил:
myTextViewTitle.text="my amazing new title"
myTextViewTitle.setContentHuggingPriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
myTextViewTitle.setContentCompressionResistancePriority(1000, forAxis: UILayoutConstraintAxis.Vertical)
myTextViewTitle.setTranslatesAutoresizingMaskIntoConstraints(false)
let views = ["new_view": myTextViewTitle]
var constrs = NSLayoutConstraint.constraintsWithVisualFormat("|-8-[new_view]-8-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
self.view.addConstraints(constrs)
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[new_view]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
self.myTextViewTitle.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[new_view(220@300)]", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
никаких результатов. С или без высоты contraint добавлен для моего textview в interface builder...
Изменить 2
мне нужен UITextView, а не UIlabel, из-за кнопки "назад", чтобы использовать путь исключения.
let exclusionPathBack:UIBezierPath = UIBezierPath(rect: CGRect(x:backButton.bounds.origin.x, y:backButton.bounds.origin.y, width:backButton.bounds.width+10, height:backButton.bounds.height))
myTextViewTitle.textContainer.exclusionPaths=[exclusionPathBack]
7 ответов
Я нашел решение.
Я был сосредоточен на высоте моего UITextView, затем я прочитал сообщение о соотношении сторон. Я хотел попробовать, и это сработало!
поэтому в раскадровке я добавил соотношение сторон для textview, и я проверил опцию "Удалить во время сборки".
в viewDidLayoutSubviews () я написал :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let contentSize = self.myTextViewTitle.sizeThatFits(self.myTextViewTitle.bounds.size)
var frame = self.myTextViewTitle.frame
frame.size.height = contentSize.height
self.myTextViewTitle.frame = frame
aspectRatioTextViewConstraint = NSLayoutConstraint(item: self.myTextViewTitle, attribute: .Height, relatedBy: .Equal, toItem: self.myTextViewTitle, attribute: .Width, multiplier: myTextViewTitle.bounds.height/myTextViewTitle.bounds.width, constant: 1)
self.myTextViewTitle.addConstraint(aspectRatioTextViewConstraint!)
}
Он отлично работает.
во-первых, отключите прокрутку UITextView. Два варианта:
- снимите флажок прокрутка включена .xib.
- [TextView setScrollEnabled: NO];
создайте UITextView и подключите его к IBOutlet (TextView). Добавьте ограничение высоты UITextView с высотой по умолчанию, подключите его к IBOutlet (TextViewHeightConstraint). Когда вы устанавливаете текст UITextView асинхронно, вы должны рассчитать высоту UITextView и установить высоту UITextView принуждение к этому. Пример кода:
CGSize sizeThatFitsTextView = [TextView sizeThatFits:CGSizeMake(TextView.frame.size.width, MAXFLOAT)];
TextViewHeightConstraint.constant = sizeThatFitsTextView.height;
в Swift 3.0, где tvHeightConstraint является ограничением высоты объекта TextView (если используется для нескольких textviews, добавьте его к входам функции):
func textViewDidChange(textView: UITextView) {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
if size.height != tvHeightConstraint.constant && size.height > textView.frame.size.height{
tvHeightConstraint.constant = size.height
textView.setContentOffset(CGPoint.zero, animated: false)
}
}
H / T к @cmi и @Pablo Ruan
в swift 2.3:
func textViewDidChange(textView: UITextView) {
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.max))
if size.height != TXV_Height.constant && size.height > textView.frame.size.height{
TXV_Height.constant = size.height
textView.setContentOffset(CGPointZero, animated: false)
}
}
Почему бы не иметь изображение для кнопки "назад" и UILabel для вашего текста и использовать autolayout для их размещения? И, возможно, третий вид на желтом фоне.
мое простое решение очень похожей проблемы:
Я использовал метки с числом строк, равным 0, вместо того, чтобы пытаться использовать текстовые поля или представления. Затем я прикрепил передний и задний края к контейнерам этикеток, которые ограничивают их ширину в моем случае, с 0 в качестве константы для ограничений. Уловка состоит в том, чтобы установить количество строк равным 0, чтобы позволить меткам расти или сжиматься в соответствии с их содержанием. Текст никогда не рубится, а высота надписей никогда не превышайте их содержимое" для всех классов разных размеров, которые я настроил для ширины (ширины контейнера в моем случае). Протестировано для IOS 8.0 и более поздних версий (также убедитесь, что "явный" не установлен рядом с атрибутами "предпочтительная ширина" для всех этикеток для ширины меток для настройки для разных классов размера) - отлично работает.
я адаптировал ваш код и использовал его для обоих: layout subview и textViewDidChange. Большое спасибо, что сделали мой день после часа устранения неполадок...
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textViewDidChange(self.recordingTitleTV)
}
func textViewDidChange(_ textView: UITextView) {
let contentSize = textView.sizeThatFits(textView.bounds.size)
var frame = textView.frame
frame.size.height = contentSize.height
textView.frame = frame
let aspectRatioTextViewConstraint = NSLayoutConstraint(item: textView, attribute: .height, relatedBy: .equal, toItem: textView, attribute: .width, multiplier: textView.bounds.height/textView.bounds.width, constant: 1)
textView.addConstraint(aspectRatioTextViewConstraint)
}