Domanda

Esiste un buon modo per regolare la dimensione di a UITextView conformarsi al suo contenuto?Diciamo per esempio che ho a UITextView che contiene una riga di testo:

"Hello world"

Quindi aggiungo un'altra riga di testo:

"Goodbye world"

Esiste un buon modo in Cocoa Touch per ottenere il file rect che manterrà tutte le righe nella vista testo in modo da poter regolare di conseguenza la vista genitore?

Come altro esempio, guarda il campo delle note per gli eventi nell'applicazione Calendario: nota come la cella (e il file UITextView contiene) si espande per contenere tutte le righe di testo nella stringa delle note.

È stato utile?

Soluzione

Funziona sia per iOS 6.1 che per 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;
}

O in Swift (funziona con 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)

Se desideri supporto per iOS 6.1 dovresti anche:

textview.scrollEnabled = NO;

Altri suggerimenti

Questo non funziona più su iOS 7 o versioni successive

In realtà esiste un modo molto semplice per ridimensionare il file UITextView all'altezza corretta del contenuto.Può essere fatto utilizzando il UITextView contentSize.

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

Una cosa da notare è che è corretto contentSize è disponibile solo Dopo IL UITextView è stato aggiunto alla vista con addSubview.Prima di ciò è uguale a frame.size

Questo non funzionerà se il layout automatico è attivo.Con il layout automatico, l'approccio generale consiste nell'utilizzare il file sizeThatFits metodo e aggiornare il file constant valore su un vincolo di altezza.

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

heightConstraint è un vincolo di layout che in genere si imposta tramite un IBOutlet collegando la proprietà al vincolo di altezza creato in uno storyboard.


Solo per aggiungere a questa straordinaria risposta, 2014, se:

[self.textView sizeToFit];

c'è una differenza di comportamento con il iPhone6+ soltanto:

enter image description here

Solo con 6+ (non 5 o 6) aggiunge "un'altra riga vuota" a UITextView.La "soluzione RL" risolve questo problema perfettamente:

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

Risolve il problema della "linea extra" su 6+.

Per effettuare un dimensionamento dinamico UITextView all'interno di un UITableViewCell, ho scoperto che la seguente combinazione funziona in Xcode 6 con l'SDK di iOS 8:

  • Aggiungere un UITextView ad a UITableViewCell e vincolarlo ai lati
  • Impostare il UITextView'S scrollEnabled proprietà a NO.Con lo scorrimento abilitato, il frame del UITextView è indipendente dalla dimensione del contenuto, ma con lo scorrimento disabilitato esiste una relazione tra i due.
  • Se la tua tabella utilizza l'altezza della riga predefinita originale di 44, calcolerà automaticamente l'altezza della riga, ma se hai modificato l'altezza della riga predefinita in qualcos'altro, potrebbe essere necessario attivare manualmente il calcolo automatico dell'altezza della riga in viewDidLoad:

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

Per il dimensionamento dinamico di sola lettura UITextViewsì, questo è tutto.Se consenti agli utenti di modificare il testo nel tuo file UITextView, devi anche:

  • Implementare il textViewDidChange: metodo del UITextViewDelegate protocollo e informarlo tableView per ridipingersi ogni volta che il testo viene modificato:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
    
  • E non dimenticare di impostare il UITextView delegare da qualche parte, in Storyboard o dentro tableView:cellForRowAtIndexPath:

Veloce:

textView.sizeToFit()

Soluzione di lavoro molto semplice che utilizza sia il codice che lo storyboard.

Per codice

textView.scrollEnabled = false

Per Storyboard

Deseleziona il Abilita scorrimento

enter image description here

Non c'è bisogno di fare altro a parte questo.

Nella mia (limitata) esperienza,

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

non rispetta i caratteri di fine riga, quindi potresti ritrovarti con caratteri molto più brevi CGSize di quanto effettivamente richiesto.

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

sembra rispettare le nuove righe.

Inoltre, il testo non viene effettivamente visualizzato nella parte superiore del file UITextView.Nel mio codice, ho impostato la nuova altezza del UITextView essere 24 pixel più grande dell'altezza restituita dal file sizeOfFont metodi.

In iOS6, puoi controllare il file contentSize proprietà di UITextView subito dopo aver impostato il testo.In iOS7, questo non funzionerà più.Se desideri ripristinare questo comportamento per iOS7, inserisci il seguente codice in una sottoclasse di 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;
    }
}

Pubblicherò la soluzione giusta in fondo alla pagina nel caso qualcuno sia coraggioso (o abbastanza disperato) da leggere fino a questo punto.

Ecco il repository gitHub per coloro che non vogliono leggere tutto quel testo: ridimensionabileTextView

Funziona con iOs7 (e credo che funzionerà con iOs8) e con il layout automatico.Non hai bisogno di numeri magici, disabilitare il layout e cose del genere. Soluzione breve ed elegante.

Penso che tutto il codice relativo ai vincoli dovrebbe andare a updateConstraints metodo.Quindi, creiamone uno nostro ResizableTextView.

Il primo problema che incontriamo qui è che non conosciamo prima la dimensione reale del contenuto viewDidLoad metodo.Possiamo prendere una strada lunga e piena di bug e calcolarla in base alla dimensione del carattere, alle interruzioni di riga, ecc.Ma abbiamo bisogno di una soluzione solida, quindi faremo:

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

Quindi ora conosciamo il contenuto reale, non importa dove siamo:prima o dopo viewDidLoad.Ora aggiungi il vincolo di altezza su textView (tramite storyboard o codice, non importa come).Adegueremo quel valore con our contentSize.height:

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

L'ultima cosa da fare è dire a superclass updateConstraints.

[super updateConstraints];

Ora la nostra classe è simile a:

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

Bello e pulito, vero?E non devi avere a che fare con quel codice nel tuo controllori!

Ma aspetta! E NESSUNA ANIMAZIONE!

Puoi facilmente animare le modifiche da apportare textView allungare dolcemente.Ecco un esempio:

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

Hai provato [textView sizeThatFits:textView.bounds] ?

Modificare:sizeThatFits restituisce la dimensione ma non ridimensiona effettivamente il componente.Non sono sicuro se è quello che vuoi, o se [textView sizeToFit] è più quello che stavi cercando.In entrambi i casi, non so se si adatterà perfettamente al contenuto che desideri, ma è la prima cosa da provare.

Un altro metodo è trovare la dimensione che occuperà una particolare stringa utilizzando il file NSString metodo:

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

Ciò restituisce la dimensione del rettangolo che si adatta alla stringa data con il carattere dato.Passa una dimensione con la larghezza desiderata e un'altezza massima, quindi puoi guardare l'altezza restituita per adattarla al testo.Esiste una versione che ti consente di specificare anche la modalità di interruzione di riga.

È quindi possibile utilizzare la dimensione restituita per modificare la dimensione della visualizzazione per adattarla.

Se non hai il UITextView utile (ad esempio, stai ridimensionando le celle della vista tabella), dovrai calcolare la dimensione misurando la stringa, quindi tenendo conto degli 8 pt di riempimento su ciascun lato di a UITextView.Ad esempio, se conosci la larghezza desiderata della visualizzazione del testo e desideri determinare l'altezza corrispondente:

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

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

Qui, ogni 8 rappresenta uno dei quattro bordi imbottiti e 100000 serve solo come dimensione massima molto grande.

In pratica, potresti voler aggiungere un extra font.leading all'altezza;questo aggiunge una riga vuota sotto il testo, che potrebbe apparire migliore se ci sono controlli visivamente pesanti direttamente sotto la visualizzazione del testo.

Sono sufficienti le seguenti cose:

  1. Ricordati solo di impostare scorrimento abilitato A NO per il tuo UITextView:

enter image description here

  1. Impostare correttamente i vincoli di layout automatico.

Potresti anche usare UITableViewAutomaticDimension.

Possiamo farlo con dei vincoli.

  1. Imposta i vincoli di altezza per UITextView.enter image description here

2.Crea IBOutlet per quel vincolo di altezza.

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

3. Non dimenticare di impostare il delegato per la tua visualizzazione testuale.

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

}

quindi aggiorna il tuo vincolo in questo modo :)

In combinazione con la risposta di Mike McMaster, potresti voler fare qualcosa del tipo:

[myTextView setDelegate: self];

...

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

Ho scoperto un modo per ridimensionare l'altezza di un campo di testo in base al testo al suo interno e anche disporre un'etichetta sotto di esso in base all'altezza del campo di testo!Ecco il codice.

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

Ragazzi, usate il layout automatico e sizetofit non funziona, quindi controllate una volta il vincolo di larghezza.Se non hai rispettato il vincolo di larghezza, l'altezza sarà accurata.

Non è necessario utilizzare altre API.solo una riga risolverebbe tutto il problema.

[_textView sizeToFit];

Qui mi preoccupavo solo dell'altezza, mantenendo fissa la larghezza e non avevo rispettato il vincolo di larghezza del mio TextView nello storyboard.

E questo per mostrare il contenuto dinamico dei servizi.

Spero che questo possa aiutare..

A partire da iOS 8, è possibile utilizzare le funzionalità di layout automatico di un UITableView per ridimensionare automaticamente un UITextView senza alcun codice personalizzato.Ho inserito un progetto github che lo dimostra in azione, ma ecco la chiave:

  1. È necessario che lo scorrimento di UITextView sia disabilitato, cosa che puoi eseguire a livello di codice o tramite il generatore di interfacce.Non verrà ridimensionato se lo scorrimento è abilitato poiché lo scorrimento consente di visualizzare contenuti più grandi.
  2. In viewDidLoad per UITableViewController, è necessario impostare un valore per stimatoRowHeight e quindi impostare il valore rowHeight A UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. La destinazione di distribuzione del progetto deve essere iOS 8 o versione successiva.

Ha funzionato bene quando avevo bisogno di creare del testo in un file UITextView adattarsi ad un'area specifica:

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

ecco la versione rapida di @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

Ho esaminato tutte le risposte e tutte mantengono la larghezza fissa e regolano solo l'altezza.Se desideri regolare anche la larghezza puoi utilizzare molto facilmente questo metodo:

quindi quando configuri la visualizzazione del testo, imposta lo scorrimento disabilitato

textView.isScrollEnabled = false

e poi nel metodo delegato func textViewDidChange(_ textView: UITextView) aggiungi questo codice:

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

Uscite:

enter image description here

enter image description here

disabilitare lo scorrimento

aggiungere costanti

e aggiungi il tuo testo

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

se usi UIScrollView dovresti aggiungere anche questo;

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

Per iOS 7.0, invece di impostare il file frame.size.height al contentSize.height (che attualmente non fa nulla) use [textView sizeToFit].

Vedere questa domanda.

Spero che questo ti aiuti:

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

se arriva qualche altro, questa soluzione funziona per me, 1"Ronnie Liew"+4"user63934" (il mio testo arriva dal servizio web):notare i 1000 (niente può essere così grande "nel mio caso")

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;

E questo è...Saluti

Il modo migliore che ho scoperto per ridimensionare l'altezza di UITextView in base alla dimensione del testo.

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

oppure puoi USARE

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

Per coloro che desiderano che la visualizzazione del testo si sposti effettivamente verso l'alto e mantenga la posizione della riga inferiore

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

L'unico codice che funzionerà è quello che utilizza "SizeToFit" come nella risposta jhibberd sopra ma in realtà non funzionerà a meno che non lo chiami VisualizzaDidAppear o collegarlo all'evento modificato del testo UITextView.

Sulla base della risposta di Nikita Took sono arrivato alla seguente soluzione in Swift che funziona su iOS 8 con layout automatico:

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

Risposta rapida:Il codice seguente calcola l'altezza del tuo textView.

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

Ora puoi impostare l'altezza del tuo textView su myTextHeight

Ecco la risposta se hai bisogno di ridimensionare textView E tableViewCell dinamicamente dentro staticTableView

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top