Frage

Gibt es eine gute Möglichkeit, die Größe von a anzupassen? UITextView seinem Inhalt entsprechen?Sagen wir zum Beispiel, ich habe eine UITextView das eine Textzeile enthält:

"Hello world"

Anschließend füge ich eine weitere Textzeile hinzu:

"Goodbye world"

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

Schauen Sie sich als weiteres Beispiel das Notizenfeld für Ereignisse in der Kalenderanwendung an – beachten Sie, wie die Zelle (und die UITextView es enthält) wird erweitert, um alle Textzeilen in der Notizzeichenfolge aufzunehmen.

War es hilfreich?

Lösung

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 außerdem:

textview.scrollEnabled = NO;

Andere Tipps

Dies funktioniert nicht mehr unter iOS 7 oder höher

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

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

Zu beachten ist, dass es richtig ist contentSize ist nur verfügbar nach Die UITextView wurde der Ansicht mit hinzugefügt addSubview.Davor ist es gleich frame.size

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

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 aus dem Jahr 2014 zu ergänzen, wenn Sie:

[self.textView sizeToFit];

Es gibt einen Unterschied im Verhalten mit dem iPhone6+ nur:

enter image description here

Nur bei 6+ (nicht bei 5s oder 6) wird der UITextView „eine weitere Leerzeile“ hinzugefügt.Die „RL-Lösung“ behebt dieses Problem perfekt:

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

Es behebt das Problem der „zusätzlichen Zeile“ auf 6+.

Um eine dynamische Dimensionierung vorzunehmen UITextView in einem UITableViewCell, Ich habe festgestellt, dass die folgende Kombination in Xcode 6 mit dem iOS 8 SDK funktioniert:

  • Füge hinzu ein UITextView zu einem UITableViewCell und beschränke es auf die Seiten
  • Stellen Sie die ein UITextView'S scrollEnabled Eigentum zu NO.Wenn das Scrollen aktiviert ist, wird der Rahmen des UITextView ist unabhängig von der 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 die Zeilenhöhen automatisch berechnet. Wenn Sie jedoch die Standardzeilenhöhe auf etwas anderes geändert haben, müssen Sie möglicherweise die automatische Berechnung der Zeilenhöhen manuell aktivieren viewDidLoad:

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

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

  • Implementieren Sie die textViewDidChange: Methode der UITextViewDelegate Protokoll, und sagen Sie es dem tableView um sich jedes Mal neu zu zeichnen, wenn der Text bearbeitet wird:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
    
  • Und vergessen Sie nicht, das einzustellen UITextView irgendwohin delegieren, entweder hinein Storyboard oder in tableView:cellForRowAtIndexPath:

Schnell:

textView.sizeToFit()

Sehr einfach funktionierende Lösung, die sowohl Code als auch Storyboard verwendet.

Per Code

textView.scrollEnabled = false

Per Storyboard

Deaktivieren Sie das Kontrollkästchen Scrollen aktivieren

enter image description here

Ansonsten ist nichts weiter zu tun.

Nach meiner (begrenzten) Erfahrung

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

respektiert keine Zeilenumbrüche, daher kann es sein, dass Sie am Ende viel kürzere Zeichen erhalten CGSize als tatsächlich erforderlich ist.

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

scheint die Zeilenumbrüche zu respektieren.

Außerdem wird der Text oben nicht wirklich gerendert UITextView.In meinem Code habe ich die neue Höhe des festgelegt UITextView 24 Pixel größer sein als die von zurückgegebene Höhe sizeOfFont Methoden.

In iOS6 können Sie das überprüfen contentSize Eigenschaft von UITextView, direkt 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;
    }
}

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

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

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

Ich denke, dass der gesamte einschränkungsbezogene Code an gehen sollte updateConstraints Methode.Also machen wir unser eigenes ResizableTextView.

Das erste Problem, auf das wir hier stoßen, besteht darin, dass wir die tatsächliche Inhaltsgröße vorher nicht kennen viewDidLoad Methode.Wir können einen langen und fehlerhaften Weg gehen und ihn anhand der Schriftgröße, der Zeilenumbrüche usw. berechnen.Aber wir brauchen eine robuste Lösung, also machen wir:

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

Jetzt kennen wir also die tatsächliche Inhaltsgröße, egal wo wir sind:vorher oder nachher viewDidLoad.Fügen Sie nun eine Höhenbeschränkung für textView hinzu (per 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 Sie tun müssen, ist, Superclass dazu aufzufordern 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 diesem Code befassen Controller!

Aber warte! Y KEINE ANIMATION!

Sie können Änderungen ganz einfach animieren, um sie vorzunehmen 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];

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 nicht [textView sizeToFit] ist mehr das, was Sie gesucht haben.In beiden Fällen weiß ich nicht, ob es perfekt zu dem von Ihnen gewünschten Inhalt passt, aber es ist das Erste, was Sie ausprobieren sollten.

Eine andere Methode besteht darin, mithilfe von die Größe zu ermitteln, die eine bestimmte Zeichenfolge einnimmt NSString Methode:

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

Dies gibt die Größe des Rechtecks ​​zurück, das zur angegebenen Zeichenfolge 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 sie an den Text anzupassen.Es gibt eine Version, mit der Sie auch den Zeilenumbruchmodus festlegen können.

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

Wenn Sie das nicht haben UITextView Praktisch (zum Beispiel, wenn Sie die Größe von Zellen in Tabellenansichten anpassen), müssen Sie die Größe berechnen, indem Sie die Zeichenfolge messen und dann die 8 Punkte Abstand 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 stellt jede 8 eine der vier gepolsterten Kanten dar und 100.000 dient lediglich als sehr große Maximalgröße.

In der Praxis möchten Sie möglicherweise ein Extra hinzufügen font.leading zur Höhe;Dadurch wird eine Leerzeile unter Ihrem Text hinzugefügt, die möglicherweise besser aussieht, wenn direkt unter der Textansicht visuell umfangreiche Steuerelemente vorhanden sind.

Folgende Dinge genügen:

  1. Denken Sie daran, es einzustellen Scrollen aktiviert Zu NEIN für dein UITextView:

enter image description here

  1. Legen Sie die Einschränkungen für das automatische Layout richtig fest.

Sie können es sogar verwenden UITableViewAutomaticDimension.

Wir können es durch Einschränkungen tun.

  1. Legen Sie Höhenbeschränkungen für UITextView fest.enter image description here

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

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

3. Vergessen Sie nicht, einen 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 :)

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

[myTextView setDelegate: self];

...

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

Ich habe eine Möglichkeit gefunden, die Höhe eines Textfelds entsprechend dem darin enthaltenen Text zu ändern und außerdem 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];

Leute, die Autolayout verwenden und eure Größe nicht funktioniert, dann überprüft bitte einmal eure Breitenbeschränkung.Wenn Sie die Breitenbeschränkung übersehen haben, ist die Höhe korrekt.

Es ist nicht erforderlich, eine andere API zu verwenden.Nur eine Zeile würde das gesamte Problem beheben.

[_textView sizeToFit];

Hier ging es mir nur um die Höhe und die Beibehaltung der Breite, und ich hatte die Breitenbeschränkung meiner Textansicht im Storyboard übersehen.

Und dies diente dazu, die dynamischen Inhalte der Dienste anzuzeigen.

Hoffe das könnte helfen..

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

  1. Für die UITextView muss das Scrollen deaktiviert sein, was Sie programmgesteuert oder über den Interface Builder tun können.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 den UITableViewController müssen Sie einen Wert für geschätzteRowHeight festlegen und dann festlegen rowHeight Zu UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. Das Ziel der Projektbereitstellung muss iOS 8 oder höher sein.

Das funktionierte gut, als ich Text in einem erstellen musste UITextView in einen bestimmten Bereich passen:

// The text must already be added to the subview, or contentviewsize will be wrong.

- (void) reduceFontToFit: (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 size:pointSize];
        tv.font = newFont;
    }
    if (pointSize != font.pointSize)
        NSLog(@"font down to %.1f from %.1f", pointSize, tv.font.pointSize);
}

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

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 ganz einfach diese Methode verwenden:

Stellen Sie beim Konfigurieren Ihrer Textansicht daher sicher, dass das Scrollen deaktiviert ist

textView.isScrollEnabled = false

und dann in der Delegate-Methode func textViewDidChange(_ textView: UITextView) füge 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:

enter image description here

enter image description here

Scrollen deaktivieren

Fügen Sie Einschränkungen hinzu

und fügen Sie Ihren Text hinzu

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

wenn du benutzt UIScrollView Sie sollten 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;
}

Für iOS 7.0, anstatt das festzulegen frame.size.height zum contentSize.height (was derzeit nichts bewirkt) verwenden [textView sizeToFit].

Sehen diese Frage.

Hoffe das hilft:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}

Wenn jemand anderes hierher kommt, 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

Der beste Weg, den ich herausgefunden habe, ist, die Höhe der UITextView entsprechend der Textgröße anzupassen.

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

oder Sie können BENUTZEN

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

Für diejenigen, die möchten, dass die Textansicht tatsächlich nach oben wandert und die Endposition beibehält

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

Der einzige Code, der funktionieren wird, ist derjenige, der „SizeToFit“ wie in der obigen jhibberd-Antwort verwendet, aber tatsächlich wird er nicht aktiviert, es sei denn, Sie rufen ihn auf ViewDidAppear oder verbinden Sie es mit dem UITextView-Textänderungsereignis.

Basierend auf der Antwort von Nikita Took bin ich in Swift auf die folgende Lösung gekommen, 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
            }
        }
    }

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 festlegen myTextHeight

Hier ist die Antwort, wenn Sie die Größe ändern müssen textView Und tableViewCell dynamisch in staticTableView

[https://stackoverflow.com/a/43137182/5360675][1]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top