565 Stimmen

Wie kann ich die Größe einer UITextView an den Inhalt anpassen?

Gibt es eine gute Möglichkeit, die Größe einer UITextView mit ihrem Inhalt übereinstimmen? Sagen wir, ich habe zum Beispiel eine UITextView die eine Textzeile enthält:

"Hello world"

Dann füge ich eine weitere Textzeile hinzu:

"Goodbye world"

Gibt es eine gute Möglichkeit in Cocoa Touch, die rect die alle Zeilen in der Textansicht enthält, so dass ich die übergeordnete Ansicht entsprechend anpassen kann?

Ein weiteres Beispiel ist das Feld "Notizen" für Ereignisse in der Kalenderanwendung - beachten Sie, wie die Zelle (und die UITextView enthält) wird erweitert, um alle Textzeilen der Notenzeichenfolge aufzunehmen.

0 Stimmen

Bitte aktualisieren Sie die korrekte Antwort, da die akzeptierte Antwort zu unnötigen Berechnungen führt; jetzt gibt es eine contentSize-Eigenschaft für dieses Problem.

0 Stimmen

Warum gibt es keine Fragen dazu, wie man das nicht dynamisch machen kann? Ich kann nicht einmal herausfinden, wie man es statisch macht. Und die bereitgestellten Lösungen scheinen nicht zu "Einschränkungen" in Storyboard außer Kraft setzen.

24voto

user63934 Punkte 251

Nach meiner (begrenzten) Erfahrung,

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

respektiert keine Zeilenumbrüche, so dass Sie am Ende eine viel kürzere CGSize als tatsächlich benötigt wird.

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

scheint die Zeilenumbrüche zu respektieren.

Außerdem wird der Text nicht am oberen Rand der Seite gerendert. UITextView . In meinem Code habe ich die neue Höhe des UITextView um 24 Pixel größer sein als die Höhe, die von der Funktion sizeOfFont Methoden.

3 Stimmen

Das erhält die Größe, als ob es den Text auf ein UILabel zeichnen würde. Wenn Sie diese Größe auf den Rahmen der uitextview setzen, dann haben Sie noch einige Scrollen notwendig in ihm.

24voto

phatmann Punkte 17730

In iOS6 können Sie die contentSize Eigenschaft von UITextView, nachdem Sie den Text festgelegt haben. Unter iOS7 wird dies nicht mehr funktionieren. Wenn Sie dieses Verhalten für iOS7 wiederherstellen möchten, platzieren Sie den folgenden Code in einer Unterklasse von 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;
    }
}

2 Stimmen

Wo kann ich mehr darüber lesen? Ich bin völlig ratlos, was das scheinbar neue Verhalten in iOS 7 angeht.

0 Stimmen

Was ist die Bedeutung der Variablen CGSize size?

0 Stimmen

Ich habe die Größe entfernt, sie sollte nicht dort sein.

19voto

Nikita Took Punkte 3960

Ich werde die richtige Lösung am Ende der Seite posten, falls jemand den Mut hat (oder verzweifelt genug ist), bis zu diesem Punkt zu lesen.

Hier ist gitHub repo für diejenigen, die nicht den ganzen Text lesen wollen: resizableTextView

Dies funktioniert mit iOs7 (und ich glaube, es wird auch mit iOs8 funktionieren) und mit Autolayout. Sie brauchen keine magischen Zahlen, deaktivieren Sie das Layout und solche Sachen. Kurze und elegante Lösung.

Ich denke, dass der gesamte Code, der sich auf Einschränkungen bezieht, in updateConstraints Methode. Also, machen wir unsere eigene ResizableTextView .

Das erste Problem, auf das wir hier stoßen, ist, dass wir die tatsächliche Größe des Inhalts vorher nicht kennen viewDidLoad Methode. Wir können einen langen und fehleranfälligen Weg nehmen und ihn anhand von Schriftgröße, Zeilenumbrüchen usw. berechnen. Aber wir brauchen eine robuste Lösung, so werden wir tun:

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

Jetzt kennen wir die tatsächliche contentSize, egal wo wir uns befinden: vor oder nach viewDidLoad . Fügen Sie nun eine Höhenbeschränkung für textView hinzu (über Storyboard oder Code, egal wie). Wir passen diesen Wert mit unserem contentSize.height :

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

Das letzte, was zu tun ist, ist der Superklasse zu sagen updateConstraints .

[super updateConstraints];

Jetzt sieht unsere Klasse so aus:

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];
}

Hübsch und sauber, oder? Und Sie müssen sich nicht mit dem Code in Ihrem Kontrolleure !

Doch halt! Y KEINE ANIMATION!

Sie können Änderungen leicht animieren, um textView sanft dehnen. Hier ist ein Beispiel:

    [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];

4 Stimmen

Verwenden Sie CGFLOAT_MAX , nicht FLT_MAX .

0 Stimmen

Ich wünschte, ich könnte Ihnen mehr als eine Stimme für diese großartige Lösung geben!!!

14voto

Mike McMaster Punkte 7513

Haben Sie versucht [textView sizeThatFits:textView.bounds] ?

Bearbeiten: sizeThatFits gibt die Größe zurück, ändert aber nicht tatsächlich die Größe der Komponente. Ich bin nicht sicher, ob es das ist, was Sie wollen, oder ob [textView sizeToFit] ist eher das, wonach Sie gesucht haben. In jedem Fall weiß ich nicht, ob es perfekt zum Inhalt passt, wie Sie es wünschen, aber es ist der erste Versuch.

2 Stimmen

Sizetofit rettet den Tag

10voto

Code Addict Punkte 156

Eine andere Methode besteht darin, die Größe einer bestimmten Zeichenkette zu ermitteln, indem man die NSString Methode:

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

Gibt die Größe des Rechtecks zurück, in das die angegebene Zeichenkette mit der angegebenen Schriftart passt. Übergeben Sie eine Größe mit der gewünschten Breite und einer maximalen Höhe, und dann können Sie sich die zurückgegebene Höhe ansehen, um den Text einzupassen. Es gibt eine Version, mit der Sie auch den Zeilenumbruchmodus angeben können.

Sie können dann die zurückgegebene Größe verwenden, um die Größe Ihrer Ansicht anzupassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X