Wie kann ich eine UITextView an ihren Inhalt anpassen?

521

Gibt es eine gute Möglichkeit, die Größe von a UITextViewan den Inhalt anzupassen? Angenommen, ich habe eine UITextView, die eine Textzeile enthält:

"Hello world"

Ich füge dann eine weitere Textzeile hinzu:

"Goodbye world"

Gibt es in Cocoa Touch eine gute Möglichkeit rect, alle Zeilen in der Textansicht zu speichern, damit ich die übergeordnete Ansicht entsprechend anpassen kann?

Sehen Sie sich als weiteres Beispiel das Notizfeld für Ereignisse in der Kalenderanwendung an. Beachten Sie, wie die Zelle (und die UITextViewdarin enthaltenen) erweitert wird, um alle Textzeilen in der Zeichenfolge der Notizen aufzunehmen.

zogh
quelle
Bitte erwägen Sie, die richtige Antwort zu aktualisieren, da die akzeptierte zu unnötigen Berechnungen führt. Jetzt gibt es eine contentSize-Eigenschaft für dieses Problem.
Juan Boero

Antworten:

610

Dies funktioniert sowohl für iOS 6.1 als auch für 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;
}

Oder in Swift (funktioniert mit Swift 4.1 in 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)

Wenn Sie Unterstützung für iOS 6.1 wünschen, sollten Sie auch:

textview.scrollEnabled = NO;
jhibberd
quelle
1
Getestet unter iOS 7, um die Größe einer UITextView in eine UITableViewCell zu ändern. Funktioniert wirklich gut. Dies ist die einzige Antwort, die endlich für mich funktioniert hat. Vielen Dank!
Alex
37
Ich brauchte das textview.scrollEnabled = NO;, um zu verhindern, dass der Text auch in iOS 7 abgeschnitten wird.
Brian
19
Ich empfehle, CGFLOAT_MAXMakro anstelle von zu verwenden MAXFLOAT. Richtig auf beiden 32/64-Bit-Plattformen.
Eonil
2
Derjenige, der vor der Eingabe in der nächsten Zeile nur geringen Schwankungen ausgesetzt ist, fügt diesen `NSRange bottom = NSMakeRange (textView.text.length -1, 1) hinzu; [textView scrollRangeToVisible: bottom]; `
ajay_nasa
4
Warum gibt es in der Swift-Version zwei separate Aufrufe von sizeThatFits (...)? Wofür ist die erste Zeile?
Nekonari
576

Dies funktioniert nicht mehr unter iOS 7 oder höher

Es gibt tatsächlich eine sehr einfache Möglichkeit, die UITextViewGröße des Inhalts auf die richtige Höhe des Inhalts zu ändern . Dies kann mit dem erfolgen UITextView contentSize.

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

Zu beachten ist, dass das Richtige contentSizeerst verfügbar ist, nachdem das UITextViewder Ansicht mit hinzugefügt wurde addSubview. Vorher ist es gleichframe.size

Dies funktioniert nicht, wenn das automatische Layout aktiviert ist. Beim automatischen Layout besteht der allgemeine Ansatz darin, die sizeThatFitsMethode zu verwenden und den constantWert für eine Höhenbeschränkung zu aktualisieren .

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

heightConstraint ist eine Layoutbeschränkung, die Sie normalerweise über ein IBOutlet einrichten, indem Sie die Eigenschaft mit der in einem Storyboard erstellten Höhenbeschränkung verknüpfen.


Nur um diese erstaunliche Antwort, 2014, hinzuzufügen, wenn Sie:

[self.textView sizeToFit];

Es gibt nur beim iPhone6 ​​+ einen Unterschied im Verhalten :

Geben Sie hier die Bildbeschreibung ein

Nur mit 6+ (nicht mit 5s oder 6) wird der UITextView "eine weitere Leerzeile" hinzugefügt. Die "RL-Lösung" behebt dies perfekt:

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

Es behebt das Problem der "zusätzlichen Leitung" bei 6+.

Ronnie Liew
quelle
2
Du hast meinen Tag gerettet. Ich hatte Probleme mit der Selbstberechnung der Klassenfunktionserweiterung und vergaß dies. Vielen Dank.
Lukasz
4
Aha! Ich habe die Höhe der Textansicht eingestellt und dann die Höhe der enthaltenen Ansicht angepasst. Anscheinend wurde dabei die Höhe der Textansicht angepasst. Wenn Sie zuerst die Höhe der enthaltenen Ansicht festlegen, funktionieren die Dinge wie erwartet (oder besser erhofft).
Hot Licks
11
Durch die Verwendung von [_textView sizeToFit] wird die contentSize-Eigenschaft aktualisiert, sodass sie nicht mehr zuvor zur scrollView hinzugefügt werden muss.
Rodrigo
1
Wenn Sie Autolayout verwenden, rufen Sie layoutIfNeededdie Übersicht auf. Dann können Sie die Höhe von greifen contentSize.
Phatmann
4
Es geht jedoch darum, die Größe des Außencontainers zu ändern. Dieses Verhalten hat sich in iOS 7 geändert. Ich zeige in der verknüpften Frage, wo sizeToFit und layoutIfNeeded hinzugefügt werden sollen.
Henrik Erlandsson
93

Um eine dynamische Größe UITextViewinnerhalb von a zu erstellen UITableViewCell, habe ich festgestellt, dass die folgende Kombination in Xcode 6 mit dem iOS 8 SDK funktioniert:

  • Fügen Sie a UITextViewzu a hinzuUITableViewCell und beschränken Sie es auf die Seiten
  • Legen Sie die UITextView‚s - scrollEnabledEigenschaft auf NO. Wenn das Scrollen aktiviert ist, ist der Frame von UITextViewunabhängig von seiner Inhaltsgröße, aber wenn das Scrollen deaktiviert ist, besteht eine Beziehung zwischen beiden.
  • Wenn Ihre Tabelle die ursprüngliche Standardzeilenhöhe von 44 verwendet, werden automatisch die Zeilenhöhen berechnet. Wenn Sie jedoch die Standardzeilenhöhe in etwas anderes geändert haben, müssen Sie möglicherweise die automatische Berechnung der Zeilenhöhen manuell aktivieren in viewDidLoad:

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

Für schreibgeschützte dynamische Größen von UITextViews ist es das. Wenn Sie Benutzern erlauben, den Text in Ihrem zu bearbeiten UITextView, müssen Sie außerdem:

  • Implementieren Sie die textViewDidChange:Methode des UITextViewDelegateProtokolls und weisen Sie das tableViewan, sich jedes Mal neu zu malen, wenn der Text bearbeitet wird:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • Und vergessen Sie nicht, den UITextViewDelegierten irgendwo in Storyboardoder in zu setzentableView:cellForRowAtIndexPath:

Brett Donald
quelle
Beste Antwort für mich. Funktionierte perfekt und UITableViewAutomaticDimension wurde in iOS 5 hinzugefügt, sodass es abwärtskompatibel ist.
Smmelzer
4
Hat bei mir nicht ganz funktioniert. Die textViewDidChange-Methode bewirkt, dass meine Tabellenansicht jedes Mal abprallt, wenn ich ein Zeichen eingebe. Ich schlage vor, dass anstelle dieser Methode in der tableView: cellForRowAtIndexPath-Methode für die Zeile mit der Textansicht die Option ".scrollEnabled" auf "NO" und die Bearbeitungsansicht "NO" verwendet wird Bildlauf aktiviert auf JA. Auf diese Weise wird beim Anzeigen nur der vollständige Text angezeigt, und beim Bearbeiten wird der vollständige Text angezeigt. Wenn Sie weiteren Text hinzufügen, bleibt die Größe gleich, wobei der frühere Text von oben
gescrollt wird
3
Außerdem habe ich der Textansicht eine> = Höhenbeschränkung hinzugefügt, da ein leeres Textfeld keine Höhe hatte und nicht angetippt werden konnte, um mit der Bearbeitung zu beginnen.
SimonTheDiver
Hervorragende Lösung. Für mich war das tableView.rowHeight = UITableViewAutomaticDimensionunnötig.
Christopher Pickslay
Nochmals vielen Dank Brett Donald! Ich habe vergessen, wie das geht und habe über 1 Jahr später wieder Ihre Antwort gefunden 😀.
Eric Conner
75

Sehr einfach zu arbeitende Lösung mit Code und Storyboard.

Nach Code

textView.scrollEnabled = false

Mit dem Storyboard

Deaktivieren Sie das Scrolling aktivieren

Geben Sie hier die Bildbeschreibung ein

Sie müssen nichts anderes tun.

Alok
quelle
5
Diese Antwort ist richtig. In StoryBoard haben Sie die TextView AutoSize genau wie ein UILabel. Alles was wir tun müssen, ist scrollEnabled = false zu setzen.
pnavk
4
Im Wesentlichen ist dies richtig: Wenn Sie Autolayout-Einschränkungen verwenden und das Scrollen beenden, funktioniert das Ganze.
Dan Rosenstark
2
Vielen Dank. Es war so einfach, einfach das Scrollen in Storyboard oder Code zu deaktivieren, es wird wie UILabel mit den Zeilen 0 sein.
samir105
@ Mansuu .... Dies ist keine garantierte Lösung, da Sie verschiedene Maßnahmen ergreifen können, um die Größe des Inhalts zu überschreiben. Wenn Sie den Text nach dem Erstellen der Ansicht ändern, wird er nur aktualisiert, wenn Sie dies festlegen bis zu. Diese Dinge gelten jedoch auch für das Setzen von numberOfLines = 0 in einem Textfeld. Wenn dies nicht funktioniert, haben Sie wahrscheinlich andere Einschränkungen, die implizit eine Höhe festlegen.
Jake T.
2
@iOS Wenn Sie eine Höhenbeschränkung hinzufügen, verringern Sie die Priorität der Beschränkungen, da dies sonst nicht funktioniert.
Alok
61

Swift:

textView.sizeToFit()
Juan Boero
quelle
14
Außerdem musste ich das Scrollen auf false setzen, damit dies funktioniert. textView.scrollEnabled = false
Tmarkiewicz
1
Sie sollten daran denken, textView.layoutIfNeeded () nach textView.sizeToFit ()
Daniel Kuta
5
@tmarkiewicz Es funktioniert, wenn der Text auf den Bildschirm Ihres Geräts passt, aber es ist ein Problem, wenn Ihr Text größer ist als der Platz auf dem Bildschirm. Sie können nicht scrollen, um den Rest des Textes zu sehen.
Francisco Romero
Das ist die Antwort!!! Keine komplizierteren Lösungen nötig !!! @FranciscoRomero Warum nicht die Textansicht in eine Tabellenzelle oder eine Sammlungsansichtszelle einfügen, dann können Sie immer durch die Tabellen- oder Sammlungsansicht scrollen ....
Ben Smith
23

Nach meiner (begrenzten) Erfahrung

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

respektiert keine Zeilenumbrüche, so dass Sie am Ende viel kürzer sein können, CGSizeals tatsächlich erforderlich ist.

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

scheint die Zeilenumbrüche zu respektieren.

Außerdem wird der Text nicht oben im Bild gerendert UITextView. In meinem Code habe ich die neue Höhe von UITextView24 Pixel größer als die von den sizeOfFontMethoden zurückgegebene Höhe festgelegt.

user63934
quelle
3
Das bekommt die Größe, als würde es den Text auf einem UILabel zeichnen. Wenn Sie diese Größe auf den Rahmen der Uitext-Ansicht einstellen, ist immer noch ein Bildlauf erforderlich.
Kevlar
22

In iOS6 können Sie die contentSizeEigenschaft von UITextView direkt nach dem Festlegen des Texts überprüfen . In iOS7 funktioniert dies nicht mehr. 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;
    }
}
Phatmann
quelle
2
Wo kann ich mehr darüber lesen? Ich bin total verloren in Bezug auf das scheinbar neue Verhalten in iOS 7 in dieser Hinsicht.
Stian Høiland
Was bedeutet die variable CGSize-Größe?
Tchelow
Ich habe die Größe entfernt, sie sollte nicht da sein.
Phatmann
18

Ich werde die richtige Lösung am Ende der Seite veröffentlichen, falls jemand mutig (oder verzweifelt genug) ist, bis zu diesem Punkt zu lesen.

Hier ist gitHub Repo für diejenigen, die den ganzen Text nicht lesen möchten: resizableTextView

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

Ich denke, dass der gesamte Code, der sich auf Einschränkungen bezieht, zur updateConstraintsMethode gehen sollte . Also, machen wir unsere eigenen ResizableTextView.

Das erste Problem, auf das wir hier stoßen, ist, dass wir die tatsächliche Größe des Inhalts vor der viewDidLoadMethode nicht kennen . Wir können einen langen und fehlerhaften Weg nehmen und ihn basierend auf Schriftgröße, Zeilenumbrüchen usw. berechnen. Aber wir brauchen eine robuste Lösung, also tun wir Folgendes:

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

Jetzt kennen wir also echte ContentSize, egal wo wir sind: vorher oder nachher viewDidLoad. Fügen Sie nun textView eine Höhenbeschränkung hinzu (über Storyboard oder Code, egal wie). Wir werden diesen Wert mit unserem anpassen 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, 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];
}

Schön und sauber, oder? Und Sie müssen sich nicht mit diesem Code in Ihren Controllern befassen !

Aber warte! Y KEINE ANIMATION!

Sie können Änderungen leicht animieren, um die textViewDehnung reibungslos zu gestalten. 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];
Nikita nahm
quelle
4
Verwenden Sie CGFLOAT_MAXnicht FLT_MAX.
Rob Mayoff
Ich wünschte, ich könnte Ihnen mehr als eine Stimme für diese großartige Lösung geben !!
Roller
13

Hast du versucht [textView sizeThatFits:textView.bounds] ?

Bearbeiten: sizeThatFits gibt die Größe zurück, ändert jedoch nicht die Größe der Komponente. Ich bin mir nicht sicher, ob Sie das wollen oder ob [textView sizeToFit]es mehr ist, wonach Sie gesucht haben. In beiden Fällen weiß ich nicht, ob es perfekt zum gewünschten Inhalt passt, aber es ist das erste, was Sie versuchen sollten.

Mike McMaster
quelle
2
sizetofit rettet den Tag
michaelsnowden
9

Eine andere Methode ist das Finden der Größe, die eine bestimmte Zeichenfolge mit der NSStringMethode annehmen wird:

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

Dies gibt die Größe des Rechtecks ​​zurück, das der angegebenen Zeichenfolge mit der angegebenen Schriftart entspricht. Übergeben Sie eine Größe mit der gewünschten Breite und einer maximalen Höhe. Anschließend können Sie die zurückgegebene Höhe anzeigen, um sie an den Text anzupassen. Es gibt eine Version, mit der Sie auch den Zeilenumbruchmodus festlegen können.

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

Code Addict
quelle
8

Wenn Sie nicht über die UITextViewpraktischen Funktionen verfügen (z. B. die Größe von Zellen in der Tabellenansicht), müssen Sie die Größe berechnen, indem Sie die Zeichenfolge messen und dann die 8-Punkt-Polsterung auf jeder Seite von a berücksichtigen UITextView. Wenn Sie beispielsweise die gewünschte Breite Ihrer Textansicht kennen und die entsprechende Höhe ermitteln möchten:

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

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

Hier macht jede 8 eine der vier gepolsterten Kanten aus, und 100000 dient nur als sehr große maximale Größe.

In der Praxis möchten Sie möglicherweise ein zusätzliches Element font.leadingzur Höhe hinzufügen . Dies fügt eine leere Zeile unter Ihrem Text hinzu, die möglicherweise besser aussieht, wenn sich direkt unter der Textansicht visuell starke Steuerelemente befinden.

Brent Royal-Gordon
quelle
perfektes Ergebnis in iOS 8.1
Logik
Polsterung war der Schlüssel für mich
Thibaut Noah
8

Wir können es durch Einschränkungen tun.

  1. Festlegen von Höhenbeschränkungen für UITextView. Geben Sie hier die Bildbeschreibung ein

2.Erstellen Sie das IBOutlet für diese Höhenbeschränkung.

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

3. Vergessen Sie nicht, den Delegaten für Ihre Textansicht festzulegen.

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

}

dann aktualisiere deine Einschränkung so :)

Kishore Kumar
quelle
Das ist ein fantastischer Spitzname!
Fattie
Nach dem Festlegen der Konstante muss [textView layoutIfNeeded] folgen. im Animationsblock. (Autolayout-Animationen machen es so.)
Will Larche
7

Folgende Dinge reichen aus:

  1. Denken Sie daran, das Aktivieren des Bildlaufs für Folgendes auf NEIN zu setzen UITextView:

Geben Sie hier die Bildbeschreibung ein

  1. Stellen Sie die Einschränkungen für das automatische Layout richtig ein.

Sie können sogar verwenden UITableViewAutomaticDimension.

Bartłomiej Semańczyk
quelle
6

In Kombination mit der Antwort von Mike McMaster möchten Sie vielleicht Folgendes tun:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}
Olie
quelle
6

Ich habe eine Möglichkeit gefunden, die Höhe eines Textfelds entsprechend dem darin enthaltenen Text zu ändern und auch eine Beschriftung darunter basierend auf der Höhe des Textfelds anzuordnen! Hier ist der Code.

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
quelle
Hier ist die '5' in y - Koordinate von UILabel die Lücke, die ich zwischen textView und Label haben möchte.
Dheeraj
6

Leute, die Autolayout verwenden und deren Größe nicht funktioniert, überprüfen Sie bitte einmal Ihre Breitenbeschränkung. Wenn Sie die Breitenbeschränkung übersehen haben, ist die Höhe genau.

Sie müssen keine andere API verwenden. Nur eine Zeile würde das ganze Problem beheben.

[_textView sizeToFit];

Hier ging es mir nur um die Höhe, um die Breite fest zu halten und um die Breitenbeschränkung meiner TextView im Storyboard zu übersehen.

Und dies sollte den dynamischen Inhalt der Dienste anzeigen.

Hoffe das könnte helfen ..

Swaroop S.
quelle
6

Ab iOS 8 ist es möglich, die automatischen Layoutfunktionen einer UITableView zu verwenden, um die Größe einer UITextView ohne benutzerdefinierten Code automatisch zu ändern. Ich habe ein Projekt in Github gestellt , das dies in Aktion demonstriert, aber hier ist der Schlüssel:

  1. In UITextView muss das Scrollen deaktiviert sein. Dies kann programmgesteuert oder über den Interface Builder erfolgen. Die Größe wird nicht geändert, wenn das Scrollen aktiviert ist, da Sie durch Scrollen den größeren Inhalt anzeigen können.
  2. In viewDidLoad für die UITableViewController, müssen Sie einen Wert für estimatedRowHeight gesetzt und stellen Sie dann das rowHeightzu UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. Das Projektbereitstellungsziel muss iOS 8 oder höher sein.
Chuck Krutsinger
quelle
1
Von solchen Antworten wird abgeraten. Den entsprechenden Code sollten Sie hier posten.
Antzi
5

Ich habe alle Antworten überprüft und alle behalten die feste Breite bei und passen nur die Höhe an. Wenn Sie auch die Breite anpassen möchten, können Sie diese Methode ganz einfach verwenden:

Wenn Sie Ihre Textansicht konfigurieren, deaktivieren Sie den Bildlauf

textView.isScrollEnabled = false

und func textViewDidChange(_ textView: UITextView)fügen Sie dann in der Delegate-Methode diesen Code hinzu:

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

Ausgänge:

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Peter Stajger
quelle
Delegate-Methode wird nicht @Peter Stajger
Mansuu genannt ....
4

Dies funktionierte gut, wenn ich Text in a machen musste UITextView einem bestimmten Bereich anpassen musste:

// Der Text muss bereits zur Unteransicht hinzugefügt worden sein, sonst ist die Inhaltsansicht falsch.

- (void) reduFontToFit: (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 Größe: pointSize];
        tv.font = newFont;
    }}
    if (pointSize! = font.pointSize)
        NSLog (@ "Schriftart bis% .1f von% .1f", pointSize, tv.font.pointSize);
}}
Bill Cheswick
quelle
4

Hier ist die schnelle Version von @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
quelle
6
Die Frage ist wirklich sprachunabhängig. Ist es wirklich notwendig, zurück zu gehen und schnelle Ports für alle Antworten auf UIKit-bezogene Fragen zu schreiben? Scheint so für ein lautes Gespräch zu sorgen.
Eremzeit
Das Problem, dass die meisten dieser Fragen keine bestimmte Programmiersprache haben, so dass Sie sie in Google finden, auch wenn Sie nach einer schnellen Sprache suchen
Fareed Alnamrouti
4

Scrollen deaktivieren

füge Konstanten hinzu

und fügen Sie Ihren Text hinzu

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

Wenn Sie verwenden UIScrollView, sollten Sie dies auch hinzufügen.

[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
quelle
3

Für iOS 7.0 wird anstelle der Einstellung frame.size.heightdie contentSize.height(die derzeit nichts tut) verwendet[textView sizeToFit] .

Siehe diese Frage .

Stian Høiland
quelle
2

Die Verwendung von UITextViewDelegate ist der einfachste Weg:

func textViewDidChange(_ textView: UITextView) {
    textView.sizeToFit()
    textviewHeight.constant = textView.contentSize.height
}
f0go
quelle
1

Hoffe das hilft:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
Dr. Marty
quelle
Das funktioniert nicht! Es verursacht einen Fehler: "lWert als linker Operand der Zuweisung erforderlich"
Leviathan
Sie können nur zuweisen textView.frame.
Jweyrich
1

Wenn andere hierher kommen, funktioniert diese Lösung für mich, 1 "Ronnie Liew" +4 "user63934" (Mein Text kommt vom Webdienst): Beachten Sie die 1000 (nichts kann "in meinem Fall" so groß sein)

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;

Und das ist ... Prost

Alejo JM
quelle
1

Der beste Weg, den ich gefunden habe, um die Höhe der UITextView entsprechend der Größe des Textes zu ändern.

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

oder Sie können verwenden

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

Für diejenigen, die möchten, dass die Textansicht tatsächlich nach oben verschoben wird und die Position der unteren Zeile beibehalten wird

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
quelle
1

Der einzige Code, der funktioniert, ist der, der 'SizeToFit' wie in der obigen Antwort von jhibberd verwendet, aber tatsächlich nicht aufgenommen wird, es sei denn, Sie rufen ihn in ViewDidAppear auf oder verbinden ihn mit dem Textänderungsereignis UITextView.

Mohammad Zekrallah
quelle
1

Basierend auf der Antwort von Nikita Took kam ich in Swift zu der folgenden Lösung, die unter iOS 8 mit Autolayout funktioniert:

    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
quelle
1

Schnelle Antwort: Der folgende Code berechnet die Höhe Ihrer Textansicht.

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

Jetzt können Sie die Höhe Ihrer Textansicht auf einstellen myTextHeight

RawMean
quelle
Entschuldigung, was bedeutet das: let attribute = [NSFontAttributeName: textView.text.font!] Ist das wirklich Swift-Code ohne Fehler?) let attribute = [NSFontAttributeName: textView.font!]
Meinten