Aktualizacja na 2019 rok
Jest to jeden z najgłupszych błędów w systemie iOS.
Podana tutaj klasa UITextViewFixed
jest ogólnie najbardziej rozsądnym rozwiązaniem.
Oto klasa:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
}
}
Nie zapomnij wyłączyć przewijania w Inspektorze!
Rozwiązanie działa poprawnie w serii ujęć
Rozwiązanie działa poprawnie w czasie wykonywania
To już koniec.
Zasadniczo powinno to być wszystko, czego potrzebujesz w większości przypadków .
Nawet jeśli zmieniasz wysokość widoku tekstowego w locie , UITextViewFixed
zwykle robi wszystko, czego potrzebujesz.
(Typowym przykładem zmiany wysokości w locie jest zmiana jej w zależności od typu użytkownika.)
Oto zepsuty UITextView od Apple ...
Oto UITextViewFixed
:
Pamiętaj, że oczywiście musisz
wyłącz scroll Przewiń w Inspektorze!
Nie zapomnij wyłączyć scrollEnabled! :)
Kilka dalszych problemów
(1) W niektórych nietypowych przypadkach - na przykład w niektórych tabelach z elastycznymi, dynamicznie zmieniającymi się wysokościami komórek - Apple robi dziwną rzecz: dodaje dodatkową przestrzeń u dołu . Nie naprawdę! To musiałaby być jedna z najbardziej irytujących rzeczy w iOS.
Oto „szybka poprawka” do dodania do powyższego, która zwykle pomaga w tym szaleństwie.
...
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) Czasami, aby naprawić kolejny subtelny bałagan Apple, musisz dodać:
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
super.setContentOffset(contentOffset, animated: false)
}
(3) Prawdopodobnie powinniśmy dodać:
contentInset = UIEdgeInsets.zero
po prostu .lineFragmentPadding = 0
w UITextViewFixed
.
Jednak ... wierzcie lub nie ... to po prostu nie działa w obecnym iOS! (Sprawdzone w 2019 r.) Może być konieczne dodanie tej linii w przyszłości.
Fakt, że UITextView
jest uszkodzony w iOS jest jednym z najdziwniejszych rzeczy na wszystkich komputerów przenośnych. Dziesięciolecie tego pytania i wciąż nie jest ustalone!
Wreszcie, jest nieco podobna wskazówka dla pola tekstowego : https://stackoverflow.com/a/43099816/294884
Zupełnie losowa wskazówka: jak dodać „...” na końcu
Często używasz UITextView „jak UILabel”. Więc chcesz, aby obcinał tekst za pomocą wielokropka „...”
Jeśli tak, dodaj trzeci wiersz kodu w „setup”:
textContainer.lineBreakMode = .byTruncatingTail
Przydatna wskazówka, jeśli chcesz mieć zerową wysokość, kiedy nie ma w ogóle tekstu
Często używasz widoku tekstu tylko do wyświetlania tekstu. Tak więc użytkownik nie może tak naprawdę niczego edytować. Używasz linii „0”, co oznacza, że widok tekstu automatycznie zmieni wysokość w zależności od liczby linii tekstu.
To świetnie, ale jeśli w ogóle nie ma tekstu, to niestety otrzymujesz taką samą wysokość, jakby był jeden wiersz tekstu !! Widok tekstu nigdy nie „znika”.
Jeśli chcesz, aby „zniknął”, po prostu dodaj to
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
}
(Zrobiłem to „1”, więc jasne jest, co się dzieje, „0” jest w porządku.)
Co z UILabel?
Podczas wyświetlania tekstu UILabel ma wiele zalet w porównaniu z UITextView. UILabel nie cierpi z powodu problemów opisanych na tej stronie kontroli jakości. Rzeczywiście powodem, dla którego wszyscy zwykle „poddajemy się” i używamy UITextView jest fakt, że UILabel jest trudny w obsłudze. W szczególności absurdalnie trudno jest po prostu poprawnie dodać wypełnienie do UILabel. W rzeczywistości tutaj jest pełna dyskusja na temat tego, jak „w końcu” poprawnie dodać dopełnienie do UILabel: https://stackoverflow.com/a/58876988/294884 W niektórych przypadkach, jeśli robisz trudny układ z dynamicznymi komórkami wysokości, czasami jest to lepiej zrobić to na poważnie dzięki UILabel.