Czy istnieje dobry sposób, aby dostosować rozmiar a w UITextView
celu dostosowania do jego zawartości? Powiedzmy na przykład, że mam UITextView
jeden wiersz tekstu:
"Hello world"
Następnie dodaję kolejny wiersz tekstu:
"Goodbye world"
Czy istnieje dobry sposób w Cocoa Touch, aby uzyskać taki, rect
który będzie zawierał wszystkie linie w widoku tekstowym, dzięki czemu mogę odpowiednio dostosować widok nadrzędny?
Jako kolejny przykład spójrz na pole notatek dla zdarzeń w aplikacji Kalendarz - zwróć uwagę na to, jak komórka (i UITextView
ona zawiera) rozwija się, aby pomieścić wszystkie wiersze tekstu w łańcuchu notatek.
Odpowiedzi:
Działa to zarówno dla iOS 6.1, jak i iOS 7:
Lub w Swift (Działa z Swift 4.1 w iOS 11)
Jeśli chcesz obsługiwać system iOS 6.1, powinieneś również:
źródło
textview.scrollEnabled = NO;
aby zapobiec odcięciu tekstu nawet w iOS 7.CGFLOAT_MAX
makra zamiastMAXFLOAT
. Właściwe na obu platformach 32/64 bitowych.To już nie działa na iOS 7 lub nowszym
W rzeczywistości istnieje bardzo łatwy sposób zmiany rozmiaru
UITextView
do odpowiedniej wysokości zawartości. Można to zrobić za pomocąUITextView
contentSize
.Jedną rzeczą jest, aby pamiętać, że prawidłowe
contentSize
jest dostępna tylko poUITextView
został dodany do widokuaddSubview
. Wcześniej jest równaframe.size
To nie zadziała, jeśli włączony jest automatyczny układ. W przypadku automatycznego układu ogólne podejście polega na użyciu
sizeThatFits
metody i zaktualizowaniuconstant
wartości w przypadku ograniczenia wysokości.heightConstraint
to ograniczenie układu, które zwykle konfiguruje się za pomocą IBOutleta, łącząc właściwość z ograniczeniem wysokości utworzonym w serii ujęć.Dodajmy do tej niesamowitej odpowiedzi, 2014, jeśli:
istnieje różnica w zachowaniu tylko w przypadku iPhone6 + :
Tylko dla 6+ (nie 5s ani 6) dodaje „jeszcze jedną pustą linię” do UITextView. „Rozwiązanie RL” rozwiązuje to idealnie:
Naprawia problem „dodatkowej linii” na 6+.
źródło
layoutIfNeeded
do superview. Następnie możesz złapać wysokośćcontentSize
.Aby dokonać dynamicznej zmiany rozmiaru
UITextView
wewnątrzUITableViewCell
, znalazłem następującą kombinację w Xcode 6 z SDK dla iOS 8:UITextView
doUITableViewCell
i ogranicz go do bokówUITextView
„sscrollEnabled
właściwośćNO
. Przy włączonym przewijaniu ramkaUITextView
jest niezależna od wielkości zawartości, ale przy wyłączonym przewijaniu zachodzi związek między nimi.Jeśli tabela korzysta z oryginalnej domyślnej wysokości wiersza 44, wówczas automatycznie obliczy wysokości wierszy, ale jeśli zmieniłeś domyślną wysokość wiersza na coś innego, być może będziesz musiał ręcznie włączyć automatyczne obliczanie wysokości wierszy w
viewDidLoad
:Dla dynamicznych rozmiarów tylko do odczytu
UITextView
, to wszystko. Jeśli pozwalasz użytkownikom edytować tekst w tobieUITextView
, musisz także:Zaimplementuj
textViewDidChange:
metodęUITextViewDelegate
protokołu i powiedz,tableView
aby odmalował się za każdym razem, gdy tekst jest edytowany:I nie zapomnij ustawić
UITextView
delegata gdzieś, wStoryboard
lub wtableView:cellForRowAtIndexPath:
źródło
tableView.rowHeight = UITableViewAutomaticDimension
było to niepotrzebne.Bardzo łatwe w obsłudze rozwiązanie wykorzystujące zarówno kod, jak i storyboard.
Według kodu
Według Storyboard
Odznacz opcję Włącz przewijanie
Nie musisz nic robić poza tym.
źródło
Szybki:
źródło
textView.scrollEnabled = false
Z mojego (ograniczonego) doświadczenia
nie szanuje znaków nowej linii, więc możesz skończyć z dużo krótszym,
CGSize
niż jest to w rzeczywistości wymagane.wydaje się respektować nowe linie.
Ponadto tekst nie jest renderowany w górnej części
UITextView
. W moim kodzie ustawiłem nową wysokość naUITextView
24 piksele większą niż wysokość zwracana przezsizeOfFont
metody.źródło
W iOS6 możesz sprawdzić
contentSize
właściwość UITextView zaraz po ustawieniu tekstu. W iOS7 to nie będzie już działać. Jeśli chcesz przywrócić to zachowanie dla iOS7, umieść następujący kod w podklasie UITextView.źródło
Na dole strony opublikuję właściwe rozwiązanie na wypadek, gdyby ktoś był odważny (lub wystarczająco zdesperowany), aby przeczytać do tego momentu.
Oto repozytorium gitHub dla tych, którzy nie chcą czytać całego tego tekstu: resizableTextView
Działa to z iOs7 (i wierzę, że będzie działać z iOs8) i z autolayout. Nie potrzebujesz magicznych liczb, wyłącz układ i takie tam.Krótkie i eleganckie rozwiązanie.
Myślę, że cały kod związany z ograniczeniami powinien przejść do
updateConstraints
metody. Stwórzmy własneResizableTextView
.Pierwszym problemem, jaki tu napotykamy, jest to, że nie znam rzeczywistej wielkości zawartości przed
viewDidLoad
metodą. Możemy przejść długą i trudną drogę i obliczyć ją na podstawie rozmiaru czcionki, podziałów linii itp. Ale potrzebujemy solidnego rozwiązania, więc zrobimy:CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
Teraz znamy prawdziwą treść Rozmiar bez względu na to, gdzie jesteśmy: przed czy po
viewDidLoad
. Teraz dodaj ograniczenie wysokości do textView (poprzez storyboard lub kod, bez względu na to, jak). Dostosujemy tę wartość za pomocą naszychcontentSize.height
:Ostatnią rzeczą do zrobienia jest powiadomienie superklasy
updateConstraints
.Teraz nasza klasa wygląda następująco:
ResizableTextView.m
Ładna i czysta, prawda? I nie musisz zajmować się tym kodem w swoich kontrolerach !
Ale poczekaj! Y BRAK ANIMACJI!
Możesz łatwo animować zmiany, aby
textView
płynnie się rozciągać. Oto przykład:źródło
CGFLOAT_MAX
, nieFLT_MAX
.Próbowałeś
[textView sizeThatFits:textView.bounds]
?Edycja: sizeThatFits zwraca rozmiar, ale tak naprawdę nie zmienia rozmiaru komponentu. Nie jestem pewien, czy tego właśnie chcesz, czy też
[textView sizeToFit]
tego więcej szukałeś. W obu przypadkach nie wiem, czy będzie idealnie pasować do treści, jak chcesz, ale to pierwsza rzecz, którą należy wypróbować.źródło
Inną metodą jest znalezienie rozmiaru, jaki konkretny ciąg znaków zajmie przy użyciu tej
NSString
metody:-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
Zwraca rozmiar prostokąta, który pasuje do danego ciągu z daną czcionką. Podaj rozmiar o pożądanej szerokości i maksymalnej wysokości, a następnie możesz spojrzeć na wysokość zwróconą w celu dopasowania do tekstu. Istnieje wersja, która pozwala również określić tryb podziału linii.
Następnie możesz użyć zwróconego rozmiaru, aby zmienić rozmiar widoku, aby go dopasować.
źródło
Jeśli nie masz pod
UITextView
ręką (na przykład dostosowujesz rozmiar komórek widoku tabeli), musisz obliczyć rozmiar, mierząc ciąg znaków, a następnie uwzględniając 8 punktów wypełnienia po każdej stronie znakuUITextView
. Na przykład, jeśli znasz pożądaną szerokość widoku tekstu i chcesz obliczyć odpowiednią wysokość:Tutaj każda 8 odpowiada jednej z czterech wyściełanych krawędzi, a 100000 służy tylko jako bardzo duży maksymalny rozmiar.
W praktyce możesz chcieć dodać dodatkową
font.leading
wysokość; dodaje to pustą linię pod tekstem, która może wyglądać lepiej, jeśli pod widokiem tekstu znajdują się ciężkie kontrolki wizualne.źródło
Możemy to zrobić za pomocą ograniczeń.
2. Utwórz IBOutlet dla tego ograniczenia wysokości.
3. nie zapomnij ustawić delegata do przeglądania tekstu.
4
następnie zaktualizuj swoje ograniczenie w ten sposób :)
źródło
Wystarczą następujące rzeczy:
UITextView
:Możesz nawet użyć
UITableViewAutomaticDimension
.źródło
W połączeniu z odpowiedzią Mike'a McMastera możesz chcieć zrobić coś takiego:
źródło
Znalazłem sposób na zmianę wielkości pola tekstowego zgodnie z zawartym w nim tekstem, a także ułożenie etykiety pod nim na podstawie wysokości pola tekstowego! Oto kod.
źródło
Faceci korzystający z autolayout i twój sizetofit nie działa, więc sprawdź raz ograniczenie szerokości. Jeśli pominąłeś ograniczenie szerokości, wysokość będzie dokładna.
Nie trzeba używać żadnego innego interfejsu API. tylko jedna linia rozwiązałaby cały problem.
Tutaj zajmowałem się tylko wysokością, utrzymując stałą szerokość i brakowało ograniczenia szerokości mojego TextView w serii ujęć.
A to miało pokazać dynamiczną treść z usług.
Mam nadzieję, że to może pomóc ..
źródło
Począwszy od systemu iOS 8, można korzystać z funkcji automatycznego układu UITableView, aby automatycznie zmieniać rozmiar UITextView bez żadnego kodu niestandardowego. W githubie umieściłem projekt, który pokazuje to w działaniu, ale oto klucz:
rowHeight
sięUITableViewAutomaticDimension
.źródło
Przejrzałem wszystkie odpowiedzi i wszystkie zachowują stałą szerokość i dostosowuję tylko wysokość. Jeśli chcesz dostosować również szerokość, możesz bardzo łatwo użyć tej metody:
więc podczas konfigurowania widoku tekstowego wyłącz przewijanie
a następnie w metodzie delegowanej
func textViewDidChange(_ textView: UITextView)
dodaj ten kod:Wyjścia:
źródło
Działało to ładnie, gdy musiałem napisać tekst w
UITextView
dopasować do określonego obszaru:źródło
oto szybka wersja @jhibberd
źródło
wyłącz przewijanie
dodaj konsternacje
i dodaj swój tekst
jeśli używasz
UIScrollView
, powinieneś to dodać;źródło
Dla iOS 7.0 zamiast ustawienia
frame.size.height
nacontentSize.height
(który obecnie nic nie robi)[textView sizeToFit]
.Zobacz to pytanie .
źródło
UITextViewDelegate to najprostszy sposób:
źródło
Mam nadzieję że to pomoże:
źródło
textView.frame
.jeśli jakikolwiek inny się tu dostanie, to rozwiązanie działa dla mnie, 1 „Ronnie Liew” +4 „user63934” (Mój tekst pochodzi z serwisu internetowego): zwróć uwagę na 1000 (nic nie może być tak duże „w moim przypadku”)
I to jest ... Na zdrowie
źródło
Najlepszy sposób, jaki odkryłem, aby zmienić rozmiar UITextView zgodnie z rozmiarem tekstu.
lub Możesz UŻYWAĆ
źródło
Dla tych, którzy chcą, aby widok tekstu przesunął się w górę i utrzymał pozycję dolnej linii
źródło
Jedyny kod, który będzie działał, to ten, który używa „SizeToFit”, jak w powyższej odpowiedzi jhibberd, ale tak naprawdę nie zostanie odebrany, chyba że wywołasz go w ViewDidAppear lub podłączysz do zdarzenia zmiany tekstu UITextView.
źródło
Na podstawie odpowiedzi Nikity Took doszedłem do następującego rozwiązania w Swift, które działa na iOS 8 z funkcją autolayout:
źródło
Szybka odpowiedź: Poniższy kod oblicza wysokość tekstu.
Teraz możesz ustawić wysokość tekstu Zobacz na
myTextHeight
źródło
let attribute = [NSFontAttributeName: textView.text.font!]
Czy to naprawdę Szybki kod bez błędów?) Czylet attribute = [NSFontAttributeName: textView.font!]