Вот обновленная версия очень полезного ответа Фатти.
Он добавляет 2 очень важные строки, которые помогли мне получить идеальный макет, работающий на iOS 10 и 11 (и, вероятно, на более низких).
д
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
translatesAutoresizingMaskIntoConstraints = true
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
translatesAutoresizingMaskIntoConstraints = false
}
}
Важными строками являются два translatesAutoresizingMaskIntoConstraints = <true/false>
утверждения!
Это удивительно удаляет все поля при всех моих обстоятельствах!
Хотя textView
не является первым респондентом, может случиться так, что есть некоторый странный нижний предел, который не может быть решен с помощью метода sizeThatFits
, который упомянут в принятом ответе.
При нажатии на textView внезапно исчезло странное нижнее поле, и все выглядело так, как должно, но только после того, как textView получил firstResponder
.
Поэтому я прочитал здесь, на SO , что включение и отключение translatesAutoresizingMaskIntoConstraints
действительно помогает при ручной настройке фрейма / границ между вызовами.
К счастью, это работает не только с настройкой кадра, но и с двумя строками setup()
, расположенными между двумя translatesAutoresizingMaskIntoConstraints
вызовами!
Это, например, очень полезно при расчете кадра вида с использованием systemLayoutSizeFitting
для UIView
. Возвращает правильный размер (чего раньше не было)!
Как и в оригинальном ответе упоминается:
Не забудьте отключить scrollEnabled в Инспекторе!
Это решение работает правильно как в раскадровке, так и во время выполнения.
Вот и все, теперь вы действительно готово!