Mam widok, który jest całkowicie programowo opracowany przy użyciu automatycznego układu. Mam UITextView w środku widoku z elementami powyżej i poniżej. Wszystko działa dobrze, ale chcę mieć możliwość rozwijania UITextView w miarę dodawania tekstu. Powinno to zepchnąć wszystko poniżej, gdy się rozszerzy.
Wiem, jak to zrobić na zasadzie „sprężyn i rozpórek”, ale czy jest na to sposób automatycznego układu? Jedynym sposobem, o którym mogę pomyśleć, jest usuwanie i ponowne dodawanie ograniczenia za każdym razem, gdy musi się rozwinąć.
ios
uitextview
autolayout
nslayoutconstraint
tharris
źródło
źródło
Odpowiedzi:
Widok zawierający UITextView zostanie przypisany do jego rozmiaru
setBounds
przez AutoLayout. Więc to właśnie zrobiłem. W superviewie początkowo wszystkie inne ograniczenia są ustawione tak, jak powinny, a na koniec umieściłem jedno specjalne ograniczenie dla wysokości UITextView i zapisałem je w zmiennej instancji.W
setBounds
metodzie zmieniłem następnie wartość stałej.źródło
textViewDidChange
tego powinno zaoszczędzić trochę kłopotów podczas tworzenia podklas i pisania kodu…textViewDidChange:
nie zostanie wywołana podczas programowego dodawania tekstu do UITextView.Podsumowanie: Wyłącz przewijanie widoku tekstu i nie ograniczaj jego wysokości.
Aby zrobić to programowo, umieść następujący kod w
viewDidLoad
:Aby to zrobić w programie Interface Builder, wybierz widok tekstu, odznacz opcję Przewijanie włączone w Inspektorze atrybutów i dodaj ograniczenia ręcznie.
Uwaga: jeśli masz inne widoki powyżej / poniżej swojego widoku tekstu, rozważ użycie
UIStackView
do ich rozmieszczenia.źródło
intrinsicContentSize
ten sposób- (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; if (self.text.length == 0) { size.height = UIViewNoIntrinsicMetric; } return size; }
. Powiedz mi, czy to działa dla Ciebie. Sam tego nie przetestowałem.Oto rozwiązanie dla osób, które wolą to wszystko robić za pomocą automatycznego układu:
Inspektor rozmiaru:
Ustaw pionowy priorytet odporności na kompresję zawartości na 1000.
Obniż priorytet wysokości wiązania, klikając „Edytuj” w obszarze Ograniczenia. Po prostu zrób to mniej niż 1000.
W Inspektorze atrybutów:
źródło
UITextView nie zapewnia intrinsicContentSize, więc musisz ją podklasować i podać. Aby rosła automatycznie, unieważnij intrinsicContentSize w layoutSubviews. Jeśli używasz czegokolwiek innego niż domyślny contentInset (czego nie polecam), może być konieczne dostosowanie obliczenia intrinsicContentSize.
źródło
setScrollEnabled:
aby zawsze ustawić go naNO
, otrzymasz nieskończoną pętlę dla stale rosnącego wewnętrznego rozmiaru zawartości.[textView sizeToFit]
wtextViewDidChange:
zwrotnego Delegat Auto Układ rosnąć lub kurczyć TextView (i przeliczyć żadnych ograniczeń utrzymaniu) po każdym naciśnięciu klawisza.-(void)layoutSubviews
i zawiń cały kod za-(CGSize)intrinsicContentSize
pomocąversion >= 7.0f && version < 7.1f
+else return [super intrinsicContentSize];
Możesz to zrobić poprzez scenorys, po prostu wyłącz „Przewijanie włączone” :)
źródło
Zauważyłem, że nie jest to zupełnie rzadkie w sytuacjach, w których nadal możesz potrzebować isScrollEnabled ustawione na true, aby umożliwić rozsądną interakcję z interfejsem użytkownika. Prostym przypadkiem jest to, gdy chcesz zezwolić na automatycznie rozwijany widok tekstu, ale nadal ograniczyć jego maksymalną wysokość do czegoś rozsądnego w UITableView.
Oto podklasa UITextView, którą wymyśliłem, która umożliwia automatyczne rozszerzanie z automatycznym układem, ale nadal można ograniczyć do maksymalnej wysokości i która będzie zarządzać przewijaniem widoku w zależności od wysokości. Domyślnie widok będzie się rozszerzał w nieskończoność, jeśli masz ustawione ograniczenia w ten sposób.
Jako bonus istnieje możliwość dołączania tekstu zastępczego podobnego do UILabel.
źródło
Możesz to również zrobić bez tworzenia podklas
UITextView
. Spójrz na moją odpowiedź na pytanie Jak dopasować UITextView do jego zawartości w systemie iOS 7?Użyj wartości tego wyrażenia:
zaktualizować
constant
SpośródtextView
„s wysokościUILayoutConstraint
.źródło
Ważna uwaga:
Ponieważ UITextView jest podklasą UIScrollView, podlega właściwości automaticAdjustsScrollViewInsets UIViewController.
Jeśli konfigurujesz układ, a TextView jest pierwszym widokiem podrzędnym w hierarchii UIViewControllers, jego contentInsets zostanie zmodyfikowany, jeśli parametr automaticAdjustsScrollViewInsets ma wartość true, co czasami powoduje nieoczekiwane zachowanie w układzie automatycznym.
Jeśli więc masz problemy z automatycznym układem i widokami tekstu, spróbuj ustawić
automaticallyAdjustsScrollViewInsets = false
na kontrolerze widoku lub przesunąć textView do przodu w hierarchii.źródło
To bardziej bardzo ważny komentarz
Kluczem do zrozumienia, dlaczego odpowiedź firmy Vitaminwater działa, są trzy rzeczy:
contentOffset
jest prawdopodobnie niczym innym jak:Aby uzyskać więcej informacji, zobacz objc scrollview i zrozumienie scrollview
Łącząc te trzy razem, łatwo zrozumiesz, że musisz zezwolić na wewnętrzną contentSize textView na pracę z ograniczeniami AutoLayout elementu textView, aby sterować logiką. To prawie tak, jakbyś textView działał jak UILabel
Aby tak się stało, musisz wyłączyć przewijanie, co w zasadzie oznacza rozmiar scrollView, rozmiar contentSize, aw przypadku dodania containerView, rozmiar containerView byłby taki sam. Kiedy są takie same, NIE masz przewijania. I byś to zrobił . Mając oznacza, że nie przewinąłeś w dół. Ani jeden punkt mniej! W rezultacie tekst textView zostanie rozciągnięty.
0
contentOffset
0
contentOffSet
Nie jest też nic warta, co oznacza, że granice scrollView i ramka są identyczne. Jeśli przewinąć 5 punktów wówczas contentOffset byłoby , w czasie, gdy będzie równa
0
contentOffset
5
scrollView.bounds.origin.y - scrollView.frame.origin.y
5
źródło
Rozwiązanie Plug and Play - Xcode 9
Układ automatyczny podobnie jak
UILabel
, z detekcją łącza , wybór tekstu , edycji i przewijania zUITextView
.Obsługuje automatycznie
Wiele z tych odpowiedzi dało mi 90%, ale żadna nie była niezawodna.
Wrzuć tę
UITextView
podklasę i jesteś dobry.źródło
Odpowiedź firmy Vitaminwater działa dla mnie.
Jeśli tekst w widoku tekstowym podskakuje w górę iw dół podczas edycji, po ustawieniu
[textView setScrollEnabled:NO];
ustawSize Inspector > Scroll View > Content Insets > Never
.Mam nadzieję, że to pomoże.
źródło
Umieść ukryty UILabel pod swoim widokiem tekstu. Linie etykiet = 0. Ustaw ograniczenia UITextView tak, aby były równe UILabel (centerX, centerY, width, height). Działa, nawet jeśli pozostawisz zachowanie przewijania textView.
źródło
BTW, zbudowałem rozwijający się UITextView przy użyciu podklasy i nadpisywania wewnętrznego rozmiaru zawartości. Odkryłem błąd w UITextView, który możesz chcieć zbadać we własnej implementacji. Oto problem:
Rozwijany widok tekstu zmniejszy się, aby pomieścić rosnący tekst, jeśli będziesz wpisywać pojedyncze litery na raz. Ale jeśli wkleisz do niego fragment tekstu, nie urosnie, ale tekst przewinie się w górę, a tekst na górze zniknie z widoku.
Rozwiązanie: Zastąp setBounds: w swojej podklasie. Z jakiegoś nieznanego powodu wklejanie spowodowało, że wartość bounds.origin.y była non-zee (33 w każdym przypadku, który widziałem). Więc przesłoniłem setBounds: aby zawsze ustawiać bounds.origin.y na zero. Naprawiono problem.
źródło
Oto szybkie rozwiązanie:
Ten problem może wystąpić, jeśli ustawiono właściwość clipsToBounds na wartość false w widoku tekstu. Jeśli go po prostu usuniesz, problem zniknie.
źródło
źródło