Актуальний для 2019 року
Це одна з найрозумніших помилок в iOS.
Клас, поданий тут, UITextViewFixed
зазвичай є найбільш розумним рішенням загалом.
Ось клас:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
}
}
Не забудьте вимкнути прокрутку, включену в Інспектор!
Рішення працює належним чином у раскадровці
Рішення працює належним чином під час виконання
Ось і все, ви закінчили.
Взагалі, це повинно бути все, що вам потрібно в більшості випадків .
Навіть якщо ви змінюєте висоту перегляду тексту на льоту , UITextViewFixed
зазвичай це все, що вам потрібно.
(Поширений приклад зміни висоти на льоту - це зміна її як тип користувача).
Ось зламаний UITextView від Apple ...
Ось UITextViewFixed
:
Зауважте, що, звичайно, потрібно
вимкніть прокруткуВключено в Інспекторі!
Не забудьте вимкнути прокруткуEnabled! :)
Деякі подальші питання
(1) У деяких незвичайних випадках - наприклад, у деяких випадках таблиць із гнучкими, що динамічно змінюються висотами комірок - Apple робить химерну річ: вони додають додаткового простору внизу . Насправді ні! Це повинно бути однією з найбільш гнівних речей в iOS.
Ось "швидке виправлення", яке слід додати до вищезазначеного, яке зазвичай допомагає в цьому безумстві.
...
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
// this is not ideal, but you can sometimes use this
// to fix the "extra space at the bottom" insanity
var b = bounds
let h = sizeThatFits(CGSize(
width: bounds.size.width,
height: CGFloat.greatestFiniteMagnitude)
).height
b.size.height = h
bounds = b
...
(2) Іноді, щоб виправити ще один тонкий плутанина Apple, потрібно додати це:
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
super.setContentOffset(contentOffset, animated: false)
}
(3) Напевно, ми повинні додати:
contentInset = UIEdgeInsets.zero
одразу після .lineFragmentPadding = 0
в UITextViewFixed
.
Однак ... вірите чи ні ... він просто не працює в поточній iOS! (Перевірено в 2019 р.) Можливо, буде потрібно додати цей рядок у майбутньому.
Те, що UITextView
зламано в iOS, є однією з найбільш дивних речей у всіх мобільних обчисленнях. Десятирічна річниця цього питання і досі не виправлена!
Нарешті, ось дещо схожа порада для текстового поля : https://stackoverflow.com/a/43099816/294884
Повністю випадкова порада: як додати "..." в кінці
Часто ви використовуєте UITextView "як UILabel". Отже, ви хочете, щоб він урізав текст за допомогою еліпсису "..."
Якщо так, додайте третій рядок коду в "налаштування":
textContainer.lineBreakMode = .byTruncatingTail
Зручна підказка, якщо ви хочете нульової висоти, коли текст зовсім немає
Часто ви використовуєте перегляд тексту, щоб відображати лише текст. Отже, користувач насправді нічого не може редагувати. Ви використовуєте рядки "0", щоб означати, що перегляд тексту автоматично змінюватиме висоту залежно від кількості рядків тексту.
Це чудово, але якщо тексту взагалі немає, то, на жаль, ви отримуєте таку ж висоту, як якщо б є один рядок тексту !! Перегляд тексту ніколи не «згасає».
Якщо ви хочете, щоб він "пішов", просто додайте це
override var intrinsicContentSize: CGSize {
var i = super.intrinsicContentSize
print("for \(text) size will be \(i)")
if text == "" { i.height = 1.0 }
print(" but we changed it to \(i)")
return i
}
(Я зробив це "1", щоб було зрозуміло, що відбувається, "0" добре.)
Що з UILabel?
Лише відображаючи текст, UILabel має багато переваг перед UITextView. UILabel не страждає від проблем, описаних на цій сторінці якості. Насправді причина, з якої ми зазвичай "відмовляємося" і просто використовуємо UITextView, це те, що з UILabel важко працювати. Зокрема, смішно важко просто додати оббивки , правильно, до UILabel. Насправді тут повна дискусія про те, як "нарешті" правильно додати прокладку до UILabel: https://stackoverflow.com/a/58876988/294884 У деяких випадках, якщо ви робите складну компоновку з осередками динамічної висоти, це іноді краще зробити це важким шляхом з UILabel.