Jak dopasować rozmiar UITextView do jego zawartości?

521

Czy istnieje dobry sposób, aby dostosować rozmiar a w UITextViewcelu dostosowania do jego zawartości? Powiedzmy na przykład, że mam UITextViewjeden wiersz tekstu:

"Hello world"

Następnie dodaję kolejny wiersz tekstu:

"Goodbye world"

Czy istnieje dobry sposób w Cocoa Touch, aby uzyskać taki, rectktó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 UITextViewona zawiera) rozwija się, aby pomieścić wszystkie wiersze tekstu w łańcuchu notatek.

Drawh
źródło
rozważ aktualizację poprawnej odpowiedzi, ponieważ zaakceptowana prowadzi do niepotrzebnych obliczeń, teraz dla tego problemu istnieje właściwość contentSize.
Juan Boero,

Odpowiedzi:

610

Działa to zarówno dla iOS 6.1, jak i iOS 7:

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    textView.frame = newFrame;
}

Lub w Swift (Działa z Swift 4.1 w iOS 11)

let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

Jeśli chcesz obsługiwać system iOS 6.1, powinieneś również:

textview.scrollEnabled = NO;
jhibberd
źródło
1
Przetestowano na iOS 7, aby zmienić rozmiar UITextView na UITableViewCell. Działa naprawdę świetnie. To jedyna odpowiedź, która w końcu dla mnie zadziałała. Dzięki!
Alex
37
Potrzebowałem, textview.scrollEnabled = NO;aby zapobiec odcięciu tekstu nawet w iOS 7.
Brian
19
Polecam używać CGFLOAT_MAXmakra zamiast MAXFLOAT. Właściwe na obu platformach 32/64 bitowych.
Eonil
2
Ten, kto napotyka niewielkie wahania przed przejściem do następnego wiersza, dodaje to `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: dół]; `
ajay_nasa
4
Dlaczego istnieją dwa osobne wezwania do sizeThatFits (...) w wersji Swift? Jaka jest pierwsza linia?
nekonari
576

To już nie działa na iOS 7 lub nowszym

W rzeczywistości istnieje bardzo łatwy sposób zmiany rozmiaru UITextViewdo odpowiedniej wysokości zawartości. Można to zrobić za pomocą UITextView contentSize.

CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

Jedną rzeczą jest, aby pamiętać, że prawidłowe contentSizejest dostępna tylko poUITextView został dodany do widoku addSubview. 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 sizeThatFitsmetody i zaktualizowaniu constantwartości w przypadku ograniczenia wysokości.

CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];
heightConstraint.constant = sizeThatShouldFitTheContent.height;

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:

[self.textView sizeToFit];

istnieje różnica w zachowaniu tylko w przypadku iPhone6 ​​+ :

wprowadź opis zdjęcia tutaj

Tylko dla 6+ (nie 5s ani 6) dodaje „jeszcze jedną pustą linię” do UITextView. „Rozwiązanie RL” rozwiązuje to idealnie:

CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;

Naprawia problem „dodatkowej linii” na 6+.

Ronnie Liew
źródło
2
Uratowałeś mi dzień. Walczyłem z rozszerzeniem funkcji klasy selfCalculating, zapominając o tym. Dziękuję Ci.
Łukasz
4
Aha! Ustawiałem wysokość widoku tekstu, a następnie dostosowywałem wysokość widoku zawierającego. Najwyraźniej, kiedy to zrobiłem, wysokość widoku tekstu była dostosowywana. Ustawienie wysokości widoku zawierającego najpierw powoduje, że wszystko działa zgodnie z oczekiwaniami (lub, lepiej, oczekiwano).
Hot Licks
11
Użycie [_textView sizeToFit] odświeża właściwość contentSize, usuwając wcześniejszy wymóg dodania jej do scrollView.
Rodrigo
1
Jeśli korzystasz z autolayout, zadzwoń layoutIfNeededdo superview. Następnie możesz złapać wysokość contentSize.
phatmann
4
Chodzi jednak o zmianę rozmiaru zewnętrznego pojemnika. To zachowanie zmieniło się w iOS 7. W powiązanym pytaniu pokazuję, gdzie dodać sizeToFit i layoutIfNeeded.
Henrik Erlandsson
93

Aby dokonać dynamicznej zmiany rozmiaru UITextView wewnątrz UITableViewCell, znalazłem następującą kombinację w Xcode 6 z SDK dla iOS 8:

  • Dodać UITextView do UITableViewCelli ogranicz go do boków
  • Ustaw UITextView„s scrollEnabledwłaściwośćNO . Przy włączonym przewijaniu ramka UITextViewjest 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:

    tableView.estimatedRowHeight = 150;
    tableView.rowHeight = UITableViewAutomaticDimension;

Dla dynamicznych rozmiarów tylko do odczytu UITextView, to wszystko. Jeśli pozwalasz użytkownikom edytować tekst w tobie UITextView, musisz także:

  • Zaimplementuj textViewDidChange:metodę UITextViewDelegateprotokołu i powiedz, tableViewaby odmalował się za każdym razem, gdy tekst jest edytowany:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • I nie zapomnij ustawić UITextViewdelegata gdzieś, w Storyboardlub wtableView:cellForRowAtIndexPath:

Brett Donald
źródło
Najlepsza odpowiedź dla mnie. Działa idealnie, a w iOS 5 dodano UITableViewAutomaticDimension, dzięki czemu jest kompatybilny wstecz.
smmelzer,
4
Nie całkiem dla mnie działało. Metoda textViewDidChange powoduje odbicie mojego widoku tabeli za każdym razem, gdy wpisuję znak. Sugeruję, że zamiast korzystać z tej metody, w metodzie tableView: cellForRowAtIndexPath dla wiersza z widokiem tekstu, jeśli jesteś w trybie tylko do odczytu, ustaw .scrollEnabled na NIE i jeśli jesteś w zestawie do edycji przewiń włączony do TAK. W ten sposób, gdy tylko wyświetlasz, zawsze pokaże pełny tekst, a podczas edycji rozpocznie się od pełnego tekstu, a po dodaniu dalszy tekst pozostanie taki sam, jak wcześniejszy tekst przewijany u góry
SimonTheDiver
3
ponadto dodałem ograniczenie> = wysokość do widoku tekstowego, ponieważ puste pole tekstowe nie miało wysokości i nie można było na nim kliknąć, aby rozpocząć edycję.
SimonTheDiver,
Doskonałe rozwiązanie Dla mnie tableView.rowHeight = UITableViewAutomaticDimensionbyło to niepotrzebne.
Christopher Pickslay
Jeszcze raz dziękuję Brett Donald! Zapomniałem, jak to zrobić, i znalazłem odpowiedź jeszcze raz ponad rok później 😀.
Eric Conner,
74

Bardzo łatwe w obsłudze rozwiązanie wykorzystujące zarówno kod, jak i storyboard.

Według kodu

textView.scrollEnabled = false

Według Storyboard

Odznacz opcję Włącz przewijanie

wprowadź opis zdjęcia tutaj

Nie musisz nic robić poza tym.

Alok
źródło
5
Ta odpowiedź jest poprawna. W StoryBoard masz TextView AutoSize, podobnie jak UILabel. Wszystko, co musimy zrobić, to ustawić scrollEnabled = false.
pnavk
4
Zasadniczo jest to poprawne: jeśli używasz ograniczeń Autolayout i wyłączasz przewijanie, wszystko działa.
Dan Rosenstark,
2
Wielkie dzięki. To było takie proste, po prostu wyłącz przewijanie w serii ujęć lub w kodzie, będzie to jak UILabel z liniami 0.
samir105
@Mansuu .... Nie jest to gwarantowane rozwiązanie, ponieważ istnieją rzeczy, które możesz zrobić, aby zastąpić wewnętrzny rozmiar treści, a jeśli zmienisz tekst po ułożeniu widoku, nie zostanie zaktualizowany, chyba że to ustawisz też w górę. Ale te rzeczy pozostają prawdziwe również dla ustawienia numberOfLines = 0 na polu tekstowym. Jeśli to nie zadziała, prawdopodobnie masz inne ograniczenia, które domyślnie ustawią wysokość.
Jake T.
2
@ iOS, jeśli dodajesz ograniczenie wysokości, zmniejsz priorytet priorytetu, w przeciwnym razie nie zadziała.
Alok
61

Szybki:

textView.sizeToFit()
Juan Boero
źródło
14
Ponadto stwierdziłem, że muszę ustawić opcję przewijania na false, aby to działało. textView.scrollEnabled = false
tmarkiewicz
1
Powinieneś pamiętać o wywołaniu textView.layoutIfNeeded () po textView.sizeToFit ()
Daniel Kuta
5
@tmarkiewicz Działa, gdy tekst mieści się na ekranie urządzenia, ale będzie problem, gdy tekst będzie większy niż miejsce na ekranie. Nie będzie można go przewijać, aby zobaczyć resztę tekstu.
Francisco Romero,
To jest odpowiedź !!! Nie ma potrzeby bardziej skomplikowanych rozwiązań !!! @FranciscoRomero Dlaczego nie umieścić widoku tekstu w komórce tabeli lub komórce widoku Colleciton, możesz zawsze przewijać widok tabeli lub Colleciton ....
Ben Smith
23

Z mojego (ograniczonego) doświadczenia

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

nie szanuje znaków nowej linii, więc możesz skończyć z dużo krótszym, CGSizeniż jest to w rzeczywistości wymagane.

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

wydaje się respektować nowe linie.

Ponadto tekst nie jest renderowany w górnej części UITextView. W moim kodzie ustawiłem nową wysokość na UITextView24 piksele większą niż wysokość zwracana przez sizeOfFontmetody.

użytkownik63934
źródło
3
To dostaje rozmiar, jakby rysował tekst na UILabel. Jeśli ustawisz ten rozmiar na ramkę uitextview, nadal będziesz potrzebować przewijania.
Kevlar,
22

W iOS6 możesz sprawdzić contentSizewł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.

- (void)setText:(NSString *)text
{
    [super setText:text];

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        CGRect rect = [self.textContainer.layoutManager usedRectForTextContainer:self.textContainer];
        UIEdgeInsets inset = self.textContainerInset;
        self.contentSize = UIEdgeInsetsInsetRect(rect, inset).size;
    }
}
phatmann
źródło
2
Gdzie mogę o tym przeczytać więcej? Jestem całkowicie zagubiony co do pozornie nowego zachowania w iOS 7 w tym zakresie.
Stian Høiland,
Jakie jest znaczenie zmiennej CGSize?
Tchelow,
Usunąłem rozmiar, nie powinien tam być.
phatmann
18

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 updateConstraintsmetody. Stwórzmy własne ResizableTextView.

Pierwszym problemem, jaki tu napotykamy, jest to, że nie znam rzeczywistej wielkości zawartości przed viewDidLoadmetodą. 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ą naszych contentSize.height:

[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
    if (constraint.firstAttribute == NSLayoutAttributeHeight) {
        constraint.constant = contentSize.height;
        *stop = YES;
    }
}];

Ostatnią rzeczą do zrobienia jest powiadomienie superklasy updateConstraints.

[super updateConstraints];

Teraz nasza klasa wygląda następująco:

ResizableTextView.m

- (void) updateConstraints {
    CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

    [self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
        if (constraint.firstAttribute == NSLayoutAttributeHeight) {
            constraint.constant = contentSize.height;
            *stop = YES;
        }
    }];

    [super updateConstraints];
}

Ł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 textViewpłynnie się rozciągać. Oto przykład:

    [self.view layoutIfNeeded];
    // do your own text change here.
    self.infoTextView.text = [NSString stringWithFormat:@"%@, %@", self.infoTextView.text, self.infoTextView.text];
    [self.infoTextView setNeedsUpdateConstraints];
    [self.infoTextView updateConstraintsIfNeeded];
    [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];
Nikita Took
źródło
4
Użyj CGFLOAT_MAX, nie FLT_MAX.
rob mayoff
Chciałbym dać ci więcej niż jeden głos na to niesamowite rozwiązanie !!
Skuter
13

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ć.

Mike McMaster
źródło
2
sizetofit ratuje dzień
michaelsnowden
9

Inną metodą jest znalezienie rozmiaru, jaki konkretny ciąg znaków zajmie przy użyciu tej NSStringmetody:

-(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ć.

Uzależniony od kodu
źródło
8

Jeśli nie masz pod UITextViewrę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 znaku UITextView. Na przykład, jeśli znasz pożądaną szerokość widoku tekstu i chcesz obliczyć odpowiednią wysokość:

NSString * string = ...;
CGFloat textViewWidth = ...;
UIFont * font = ...;

CGSize size = CGSizeMake(textViewWidth - 8 - 8, 100000);
size.height = [string sizeWithFont:font constrainedToSize:size].height + 8 + 8;

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.leadingwysokość; dodaje to pustą linię pod tekstem, która może wyglądać lepiej, jeśli pod widokiem tekstu znajdują się ciężkie kontrolki wizualne.

Brent Royal-Gordon
źródło
doskonały wynik w iOS 8.1
Logic
Padding był dla mnie kluczem
thibaut noah
8

Możemy to zrobić za pomocą ograniczeń.

  1. Ustaw ograniczenia wysokości dla UITextView. wprowadź opis zdjęcia tutaj

2. Utwórz IBOutlet dla tego ograniczenia wysokości.

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *txtheightconstraints;

3. nie zapomnij ustawić delegata do przeglądania tekstu.

4

-(void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    NSLog(@"this is updating height%@",NSStringFromCGSize(newFrame.size));
    [UIView animateWithDuration:0.2 animations:^{
                  _txtheightconstraints.constant=newFrame.size.height;
    }];

}

następnie zaktualizuj swoje ograniczenie w ten sposób :)

Kishore Kumar
źródło
to FANTASTYCZNY pseudonim!
Fattie
Po ustawieniu stałej musi następować [textView layoutIfNeeded]; w bloku animacji. (Animacje autoukładu robią to w ten sposób.)
Will Larche,
7

Wystarczą następujące rzeczy:

  1. Pamiętaj tylko, aby ustawić przewijanie włączone na NIE dla UITextView:

wprowadź opis zdjęcia tutaj

  1. Prawidłowo ustaw ograniczenia automatycznego układu.

Możesz nawet użyć UITableViewAutomaticDimension.

Bartłomiej Semańczyk
źródło
6

W połączeniu z odpowiedzią Mike'a McMastera możesz chcieć zrobić coś takiego:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}
Olie
źródło
6

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.

UITextView *_textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 10)];
NSString *str = @"This is a test text view to check the auto increment of height of a text view. This is only a test. The real data is something different.";
_textView.text = str;

[self.view addSubview:_textView];
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5 + frame.origin.y + frame.size.height, 300, 20)];
lbl.text = @"Hello!";
[self.view addSubview:lbl];
dheeraj
źródło
Tutaj „5” we współrzędnej y UILabel to odstęp, który chcę między textView i Label.
dheeraj
6

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.

[_textView sizeToFit];

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 ..

Swaroop S
źródło
6

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:

  1. UITextView musi mieć wyłączone przewijanie, co można zrobić programowo lub za pomocą konstruktora interfejsu. Nie będzie się zmieniać rozmiaru, jeśli włączone jest przewijanie, ponieważ przewijanie umożliwia przeglądanie większej zawartości.
  2. W viewDidLoad dla UITableViewController, należy ustawić wartość dla estimatedRowHeight a następnie ustawić rowHeightsię UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. Celem wdrożenia projektu musi być system iOS 8 lub nowszy.
Chuck Krutsinger
źródło
1
Tego rodzaju odpowiedzi są odradzane. Powinieneś opublikować odpowiedni kod tutaj.
Antzi
5

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

textView.isScrollEnabled = false

a następnie w metodzie delegowanej func textViewDidChange(_ textView: UITextView)dodaj ten kod:

func textViewDidChange(_ textView: UITextView) {
    let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
    textView.frame = CGRect(origin: textView.frame.origin, size: newSize)
}

Wyjścia:

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Peter Stajger
źródło
metoda delegowania nie jest wywoływana @Peter Stajger
Mansuu ....
4

Działało to ładnie, gdy musiałem napisać tekst w UITextView dopasować do określonego obszaru:

// Tekst musi być już dodany do widoku częściowego, w przeciwnym razie rozmiar treści będzie niepoprawny.

- (void) zmniejszFontToFit: (UITextView *) tv {
    UIFont * font = tv.font;
    double pointSize = font.pointSize;

    while (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        pointSize - = 1,0;
        UIFont * newFont = [UIFont fontWithName: font.fontName rozmiar: pointSize];
        tv.font = newFont;
    }
    if (pointSize! = font.pointSize)
        NSLog (@ "czcionka do% .1f od% .1f", pointSize, tv.font.pointSize);
}
Bill Cheswick
źródło
4

oto szybka wersja @jhibberd

    let cell:MsgTableViewCell! = self.tableView.dequeueReusableCellWithIdentifier("MsgTableViewCell", forIndexPath: indexPath) as? MsgTableViewCell
    cell.msgText.text = self.items[indexPath.row]
    var fixedWidth:CGFloat = cell.msgText.frame.size.width
    var size:CGSize = CGSize(width: fixedWidth,height: CGFloat.max)
    var newSize:CGSize = cell.msgText.sizeThatFits(size)
    var newFrame:CGRect = cell.msgText.frame;
    newFrame.size = CGSizeMake(CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), newSize.height);
    cell.msgText.frame = newFrame
    cell.msgText.frame.size = newSize        
    return cell
Fareed Alnamrouti
źródło
6
Pytanie jest naprawdę niezależne od języka. Czy naprawdę trzeba wracać i pisać szybkie porty dla wszystkich odpowiedzi na pytania związane z UIKit? Wydaje się, że to powoduje głośną rozmowę.
eremzeit,
problem polegający na tym, że większość tych pytań nie ma określonego języka programowania, więc znajdziesz go w Google, nawet jeśli szukasz szybkiego języka
Fareed Alnamrouti
4

wyłącz przewijanie

dodaj konsternacje

i dodaj swój tekst

[yourTextView setText:@"your text"];
[yourTextView layoutIfNeeded];

jeśli używasz UIScrollView, powinieneś to dodać;

[yourScrollView layoutIfNeeded];

-(void)viewDidAppear:(BOOL)animated{
    CGRect contentRect = CGRectZero;

    for (UIView *view in self.yourScrollView.subviews) {
         contentRect = CGRectUnion(contentRect, view.frame);
    }
    self.yourScrollView.contentSize = contentRect.size;
}
alicanozkara
źródło
3

Dla iOS 7.0 zamiast ustawienia frame.size.heightna contentSize.height(który obecnie nic nie robi) [textView sizeToFit].

Zobacz to pytanie .

Stian Høiland
źródło
2

UITextViewDelegate to najprostszy sposób:

func textViewDidChange(_ textView: UITextView) {
    textView.sizeToFit()
    textviewHeight.constant = textView.contentSize.height
}
f0go
źródło
1

Mam nadzieję że to pomoże:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
Dr Marty
źródło
To nie działa! Powoduje błąd: „wymagana wartość jako lewy argument przypisania”
lewiatan
Możesz przypisać tylko do textView.frame.
jweyrich
1

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”)

UIFont *fontNormal = [UIFont fontWithName:FONTNAME size:FONTSIZE];

NSString *dealDescription = [client objectForKey:@"description"];

//4
CGSize textSize = [dealDescription sizeWithFont:fontNormal constrainedToSize:CGSizeMake(containerUIView.frame.size.width, 1000)];

CGRect dealDescRect = CGRectMake(10, 300, containerUIView.frame.size.width, textSize.height);

UITextView *dealDesc = [[[UITextView alloc] initWithFrame:dealDescRect] autorelease];

dealDesc.text = dealDescription;
//add the subview to the container
[containerUIView addSubview:dealDesc];

//1) after adding the view
CGRect frame = dealDesc.frame;
frame.size.height = dealDesc.contentSize.height;
dealDesc.frame = frame;

I to jest ... Na zdrowie

Alejo JM
źródło
1

Najlepszy sposób, jaki odkryłem, aby zmienić rozmiar UITextView zgodnie z rozmiarem tekstu.

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX)];

lub Możesz UŻYWAĆ

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX) lineBreakMode:NSLineBreakByTruncatingTail];
Manju
źródło
1

Dla tych, którzy chcą, aby widok tekstu przesunął się w górę i utrzymał pozycję dolnej linii

CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;

if(frame.size.height > textView.frame.size.height){
    CGFloat diff = frame.size.height - textView.frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y - diff, textView.frame.size.width, frame.size.height);
}
else if(frame.size.height < textView.frame.size.height){
    CGFloat diff = textView.frame.size.height - frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y + diff, textView.frame.size.width, frame.size.height);
}
Gal Blank
źródło
1

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.

Mohammad Zekrallah
źródło
1

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:

    descriptionTxt.scrollEnabled = false
    descriptionTxt.text = yourText

    var contentSize = descriptionTxt.sizeThatFits(CGSizeMake(descriptionTxt.frame.size.width, CGFloat.max))
    for c in descriptionTxt.constraints() {
        if c.isKindOfClass(NSLayoutConstraint) {
            var constraint = c as! NSLayoutConstraint
            if constraint.firstAttribute == NSLayoutAttribute.Height {
                constraint.constant = contentSize.height
                break
            }
        }
    }
Apfelsaft
źródło
1

Szybka odpowiedź: Poniższy kod oblicza wysokość tekstu.

                let maximumLabelSize = CGSize(width: Double(textView.frame.size.width-100.0), height: DBL_MAX)
                let options = NSStringDrawingOptions.TruncatesLastVisibleLine | NSStringDrawingOptions.UsesLineFragmentOrigin
                let attribute = [NSFontAttributeName: textView.font!]
                let str = NSString(string: message)
                let labelBounds = str.boundingRectWithSize(maximumLabelSize,
                    options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                    attributes: attribute,
                    context: nil)
                let myTextHeight = CGFloat(ceilf(Float(labelBounds.height)))

Teraz możesz ustawić wysokość tekstu Zobacz na myTextHeight

RawMean
źródło
Przepraszam, co to znaczy: let attribute = [NSFontAttributeName: textView.text.font!] Czy to naprawdę Szybki kod bez błędów?) Czy let attribute = [NSFontAttributeName: textView.font!]
chodziło