Обновленный на 2019 год
Это одна из самых глупых ошибок в iOS.
Класс, данный здесь, UITextViewFixed
обычно является наиболее разумным решением в целом.
Вот класс:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
}
}
Не забудьте отключить scrollEnabled в Инспекторе!
Решение работает правильно в раскадровке
Решение работает правильно во время выполнения
Вот и все, вы сделали.
В общем, это должно быть все, что вам нужно в большинстве случаев .
Даже если вы изменяете высоту текстового представления на лету , UITextViewFixed
обычно делает все, что вам нужно.
(Типичным примером изменения высоты на лету является изменение ее по типу пользователя.)
Вот сломанный UITextView от Apple ...
Вот UITextViewFixed
:
Обратите внимание, что, конечно, вы должны
отключите scrollEnabled в Инспекторе!
Не забудьте отключить scrollEnabled! :)
Некоторые дальнейшие проблемы
(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 не страдает от проблем, описанных на этой странице QA. Действительно, причина, по которой мы все обычно «сдаемся» и просто используем UITextView, заключается в том, что с UILabel трудно работать. В частности, до смешного трудно просто добавить отступы в UILabel. На самом деле, здесь подробно обсуждается, как «наконец» правильно добавить заполнение в UILabel: https://stackoverflow.com/a/58876988/294884 В некоторых случаях, если вы делаете сложный макет с динамическими ячейками высоты, иногда лучше сделать это нелегко с UILabel.