¿Cómo dimensiono un UITextView a su contenido?

521

¿Hay una buena manera de ajustar el tamaño de un UITextViewpara que se ajuste a su contenido? Digamos, por ejemplo, que tengo un UITextViewque contiene una línea de texto:

"Hello world"

Luego agrego otra línea de texto:

"Goodbye world"

¿Hay una buena manera en Cocoa Touch para obtener el rectque contendrá todas las líneas en la vista de texto para que pueda ajustar la vista principal en consecuencia?

Como otro ejemplo, mire el campo de notas para eventos en la aplicación Calendario: observe cómo la celda (y la UITextViewque contiene) se expande para contener todas las líneas de texto en la cadena de notas.

Drew
fuente
considere actualizar la respuesta correcta, ya que la aceptada conduce a cálculos innecesarios, ahora hay una propiedad contentSize para este problema.
Juan Boero

Respuestas:

610

Esto funciona tanto para iOS 6.1 como para 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 en Swift (funciona con Swift 4.1 en 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)

Si desea soporte para iOS 6.1, entonces también debe:

textview.scrollEnabled = NO;
jhibberd
fuente
1
Probado en iOS 7 para redimensionar un UITextView en un UITableViewCell. Funciona muy bien Esta es la única respuesta que finalmente funcionó para mí. ¡Gracias!
Alex
37
Necesitaba textview.scrollEnabled = NO;para evitar que el texto se cortara incluso en iOS 7.
Brian
19
Recomiendo usar CGFLOAT_MAXmacro en lugar de MAXFLOAT. Apropiado en ambas plataformas de 32/64 bits.
Eonil
3
El que enfrenta poca fluctuación antes de ingresar en la siguiente línea agrega este `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: bottom]; `
ajay_nasa
44
¿Por qué hay dos llamadas separadas a sizeThatFits (...) en la versión Swift? ¿Para qué es la primera línea?
nekonari
576

Esto ya no funciona en iOS 7 o superior

En realidad, hay una manera muy fácil de cambiar el tamaño del contenido UITextViewa su altura correcta. Se puede hacer usando el UITextView contentSize.

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

Una cosa a destacar es que la correcta contentSizesólo está disponible después de la UITextViewha sido añadido a la vista con addSubview. Antes de eso es igual aframe.size

Esto no funcionará si el diseño automático está activado. Con el diseño automático, el enfoque general es utilizar el sizeThatFitsmétodo y actualizar el constantvalor en una restricción de altura.

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

heightConstraint es una restricción de diseño que normalmente configura a través de un IBOutlet al vincular la propiedad a la restricción de altura creada en un guión gráfico.


Solo para agregar a esta increíble respuesta, 2014, si usted:

[self.textView sizeToFit];

Hay una diferencia de comportamiento solo con el iPhone6 ​​+ :

ingrese la descripción de la imagen aquí

Con el 6+ solamente (no el 5s o el 6) agrega "una línea en blanco más" al UITextView. La "solución RL" soluciona esto perfectamente:

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

Soluciona el problema de "línea extra" en 6+.

Ronnie Liew
fuente
2
Salvaste mi día. Estaba luchando con la extensión de función de clase de cálculo automático olvidando esto. Gracias.
Lukasz
44
¡Ajá! Estaba configurando la altura de la vista de texto y luego ajustando la altura de la vista que lo contenía. Aparentemente, cuando hice eso, la altura de la vista de texto se estaba ajustando. Establecer la altura de la vista que contiene primero hace que las cosas funcionen como se espera (o, mejor, se espera).
Hot Licks
11
El uso de [_textView sizeToFit] actualiza la propiedad contentSize, eliminando el requisito de agregarlo previamente a scrollView.
Rodrigo
1
Si usa la distribución automática, llame layoutIfNeededa la supervista. Entonces puedes tomar la altura desde contentSize.
phatmann
44
Sin embargo, se trata de cambiar el tamaño del contenedor exterior. Ese comportamiento ha cambiado en iOS 7. Muestro en la pregunta vinculada dónde agregar sizeToFit y layoutIfNeeded.
Henrik Erlandsson
93

Para realizar un dimensionamiento dinámico UITextViewdentro de a UITableViewCell, encontré que la siguiente combinación funciona en Xcode 6 con el SDK de iOS 8:

  • Agregue a UITextViewa a UITableViewCelly restrinja a los lados
  • Ajuste el UITextView's scrollEnabledpropiedad a NO. Con el desplazamiento habilitado, el marco del archivo UITextViewes independiente de su tamaño de contenido, pero con el desplazamiento deshabilitado, existe una relación entre los dos.
  • Si su tabla utiliza la altura de fila predeterminada original de 44, calculará automáticamente las alturas de fila, pero si cambió la altura de fila predeterminada a otra, es posible que deba activar manualmente el cálculo automático de las alturas de fila en viewDidLoad:

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

Para dimensionamiento dinámico de solo lectura UITextView, eso es todo. Si está permitiendo que los usuarios editen el texto en su UITextView, también necesita:

  • Implemente el textViewDidChange:método del UITextViewDelegateprotocolo y dígale tableViewque se repinte cada vez que se edite el texto:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • Y no olvide establecer el UITextViewdelegado en algún lugar, ya sea en Storyboardo entableView:cellForRowAtIndexPath:

Brett Donald
fuente
La mejor respuesta para mi. Funcionó perfectamente y UITableViewAutomaticDimension se agregó en iOS 5, por lo que es compatible con versiones anteriores.
smmelzer
44
No me funcionó del todo. El método textViewDidChange hace que mi vista de tabla rebote cada vez que escribo un carácter. Lo que sugiero es que, en lugar de usar ese método, en el método tableView: cellForRowAtIndexPath, para la fila con la vista de texto, si está en un modo de solo lectura establecido .scrollEnabled en NO, y si está en un conjunto de vista de edición desplazamiento habilitado a SÍ. De esta manera, al mostrarlo siempre se mostrará el texto completo y al editar comenzará con el texto completo y, a medida que agregue más texto, seguirá siendo del mismo tamaño con el texto anterior desplazándose desde la parte superior
SimonTheDiver
3
Además, agregué una restricción de altura> = a la vista de texto, ya que un campo de texto vacío no tenía altura y no se podía tocar para comenzar a editar.
SimonTheDiver
Excelente solucion. Para mí, tableView.rowHeight = UITableViewAutomaticDimensionfue innecesario.
Christopher Pickslay
Gracias de nuevo Brett Donald! Olvidé cómo hacer esto y encontré tu respuesta una vez más más de 1 año después 😀.
Eric Conner
76

Solución de trabajo muy fácil usando código y guión gráfico.

Por código

textView.scrollEnabled = false

Por Storyboard

Desmarca la opción Habilitar desplazamiento

ingrese la descripción de la imagen aquí

No es necesario hacer nada aparte de esto.

Alok
fuente
55
Esta respuesta es correcta. En StoryBoard tienes TextView AutoSize como un UILabel. Todo lo que necesitamos hacer es establecer scrollEnabled = false.
pnavk
44
Esencialmente, esto es correcto: si está utilizando restricciones de Autolayout y desactiva el desplazamiento, todo funciona.
Dan Rosenstark
2
Muchas gracias. Era así de simple, simplemente deshabilita el desplazamiento en el guión gráfico o el código, será como UILabel con líneas 0.
samir105
@Mansuu ... Esta no es una solución garantizada, ya que hay cosas que puede hacer para anular el tamaño del contenido intrínseco, y si cambia el texto después de que se presenta la vista, no se actualizará a menos que establezca arriba también. Pero, esas cosas siguen siendo ciertas para establecer numberOfLines = 0 en un campo de texto, también. Si esto no funciona, probablemente tenga otras restricciones que implícitamente establecerán una altura.
Jake T.
2
@iOS si está agregando restricciones de altura, haga que la prioridad de las restricciones sea más baja, de lo contrario no funcionará.
Alok
61

Rápido:

textView.sizeToFit()
Juan boero
fuente
14
Además, descubrí que necesitaba establecer el desplazamiento habilitado en falso para que esto funcione. textView.scrollEnabled = false
tmarkiewicz
1
Debe recordar llamar a textView.layoutIfNeeded () después de textView.sizeToFit ()
Daniel Kuta
55
@tmarkiewicz Funciona cuando el texto se ajusta en la pantalla de su dispositivo, pero será un problema cuando su texto sea más grande que el espacio que hay en la pantalla. No podrá desplazarse para ver el resto del texto.
Francisco Romero
¡¡¡Esta es la respuesta!!! ¡No hay necesidad de soluciones más complicadas! @FranciscoRomero ¿Por qué no colocar la vista de texto en una celda de tabla o en una celda de vista de colección? Entonces siempre puede desplazarse por la tabla o la vista de colección ...
Ben Smith
23

En mi experiencia (limitada),

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

no respeta los caracteres de nueva línea, por lo que puede terminar con un formato mucho más corto de lo CGSizeque realmente se requiere.

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

parece respetar las nuevas líneas.

Además, el texto no se representa realmente en la parte superior de UITextView. En mi código, configuré la nueva altura de UITextView24 píxeles más grande que la altura devuelta por los sizeOfFontmétodos.

usuario63934
fuente
3
Eso obtiene el tamaño como si dibujara el texto en un UILabel. Si establece ese tamaño en el marco de uitextview, todavía tendrá que desplazarse un poco.
Kevlar
22

En iOS6, puede verificar la contentSizepropiedad de UITextView justo después de configurar el texto. En iOS7, esto ya no funcionará. Si desea restaurar este comportamiento para iOS7, coloque el siguiente código en una subclase de 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
fuente
2
¿Dónde puedo leer más sobre esto? Estoy totalmente perdido en cuanto al comportamiento aparentemente nuevo en iOS 7 con respecto a esto.
Stian Høiland
¿Cuál es el significado del tamaño variable de CGSize?
Tchelow
Eliminé el tamaño, no se suponía que estuviera allí.
phatmann
18

Publicaré la solución correcta en la parte inferior de la página en caso de que alguien sea valiente (o lo suficientemente desesperado) como para leer hasta este punto.

Aquí está el repositorio de gitHub para aquellos que no quieren leer todo ese texto: resizableTextView

Esto funciona con iOs7 (y creo que funcionará con iOs8) y con autolayout. No necesita números mágicos, deshabilite el diseño y cosas así. Solución corta y elegante.

Creo que todo el código relacionado con restricciones debería ir al updateConstraintsmétodo. Entonces, hagamos el nuestro ResizableTextView.

El primer problema que encontramos aquí es que no conocemos el tamaño real del contenido antes del viewDidLoadmétodo. Podemos tomar un camino largo y con errores y calcularlo en función del tamaño de fuente, los saltos de línea, etc. Pero necesitamos una solución robusta, así que haremos:

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

Así que ahora sabemos contenido real Tamaño sin importar dónde estemos: antes o después viewDidLoad. Ahora agregue restricción de altura en textView (a través de guión gráfico o código, no importa cómo). Ajustaremos ese valor con nuestro contentSize.height:

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

Lo último que debe hacer es decirle a la superclase updateConstraints.

[super updateConstraints];

Ahora nuestra clase se ve así:

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

Bonita y limpia, ¿verdad? ¡Y no tiene que lidiar con ese código en sus controladores !

¡Pero espera! Y NO ANIMACIÓN!

Puede animar fácilmente los cambios para que se textViewestiren suavemente. Aquí hay un ejemplo:

    [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
fuente
44
Uso CGFLOAT_MAX, no FLT_MAX.
rob mayoff
¡Ojalá pudiera darle más de un voto por esta increíble solución!
Scooter
13

¿Lo intentaste [textView sizeThatFits:textView.bounds]?

Editar: sizeThatFits devuelve el tamaño pero en realidad no cambia el tamaño del componente. No estoy seguro de si eso es lo que quieres o si [textView sizeToFit]es más lo que estabas buscando. En cualquier caso, no sé si se ajustará perfectamente al contenido que desea, pero es lo primero que debe intentar.

Mike McMaster
fuente
2
sizetofit salva el día
michaelsnowden
9

Otro método es encontrar el tamaño que tomará una cadena particular usando el NSStringmétodo:

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

Esto devuelve el tamaño del rectángulo que se ajusta a la cadena dada con la fuente dada. Pase un tamaño con el ancho deseado y una altura máxima, y ​​luego puede ver la altura devuelta para ajustarse al texto. Existe una versión que también le permite especificar el modo de salto de línea.

Luego puede usar el tamaño devuelto para cambiar el tamaño de su vista para que se ajuste.

Adicto al Código
fuente
8

Si no tiene a UITextViewmano (por ejemplo, está dimensionando las celdas de la vista de tabla), tendrá que calcular el tamaño midiendo la cadena y luego teniendo en cuenta los 8 puntos de relleno a cada lado de a UITextView. Por ejemplo, si conoce el ancho deseado de su vista de texto y desea calcular la altura correspondiente:

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

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

Aquí, cada 8 representa uno de los cuatro bordes acolchados, y 100000 solo sirve como un tamaño máximo muy grande.

En la práctica, es posible que desee agregar un extra font.leadinga la altura; esto agrega una línea en blanco debajo de su texto, que puede verse mejor si hay controles visualmente pesados ​​directamente debajo de la vista de texto.

Brent Royal-Gordon
fuente
resultado perfecto en iOS 8.1
Lógica
El relleno fue la clave para mí
thibaut noah
8

Podemos hacerlo por restricciones.

  1. Establecer restricciones de altura para UITextView. ingrese la descripción de la imagen aquí

2.Cree IBOutlet para esa restricción de altura.

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

3.no olvide establecer delegado para su vista de texto.

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

}

luego actualice su restricción así :)

Kishore Kumar
fuente
ese es un apodo FANTÁSTICO!
Fattie
La configuración de la constante debe ser seguida por [textView layoutIfNeeded]; en el bloque de animación (Las animaciones de Autolayout lo hacen así.)
Will Larche
7

Las siguientes cosas son suficientes:

  1. Solo recuerde establecer el desplazamiento habilitado en NO para su UITextView:

ingrese la descripción de la imagen aquí

  1. Establezca correctamente las restricciones de diseño automático.

Incluso puedes usarlo UITableViewAutomaticDimension.

Bartłomiej Semańczyk
fuente
6

En combinación con la respuesta de Mike McMaster, es posible que desee hacer algo como:

[myTextView setDelegate: self];

...

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

¡Encontré una forma de cambiar el tamaño de la altura de un campo de texto de acuerdo con el texto dentro de él y también organizar una etiqueta debajo de él en función de la altura del campo de texto! Aquí está el código.

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
fuente
Aquí el '5' en la coordenada y de UILabel es el espacio que quiero entre textView y Label.
dheeraj
6

Chicos que usan autolayout y su sizetofit no funciona, luego verifiquen su restricción de ancho una vez. Si se había perdido la restricción de ancho, entonces la altura será precisa.

No es necesario usar ninguna otra API. solo una línea solucionaría todo el problema.

[_textView sizeToFit];

Aquí, solo me preocupaba la altura, mantener el ancho fijo y me había perdido la restricción de ancho de mi TextView en el guión gráfico.

Y esto fue para mostrar el contenido dinámico de los servicios.

Espero que esto pueda ayudar ...

Swaroop S
fuente
6

A partir de iOS 8, es posible utilizar las características de diseño automático de un UITableView para cambiar automáticamente el tamaño de un UITextView sin ningún código personalizado. He puesto un proyecto en github que demuestra esto en acción, pero aquí está la clave:

  1. UITextView debe tener el desplazamiento deshabilitado, lo que puede hacer mediante programación o mediante el generador de interfaces. No cambiará de tamaño si el desplazamiento está habilitado porque el desplazamiento le permite ver el contenido más grande.
  2. En viewDidLoad para UITableViewController, debe establecer un valor para estimadoRowHeight y luego establecerlo rowHeighten UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. El objetivo de implementación del proyecto debe ser iOS 8 o superior.
Chuck Krutsinger
fuente
1
Se desaconseja este tipo de respuestas. Debe publicar el código relevante aquí.
Antzi
5

Revisé todas las respuestas y todas mantienen un ancho fijo y solo ajusto la altura. Si desea ajustar también el ancho, puede usar fácilmente este método:

así que al configurar su vista de texto, configure el desplazamiento deshabilitado

textView.isScrollEnabled = false

y luego en el método delegado func textViewDidChange(_ textView: UITextView)agregue este código:

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

Salidas:

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Peter Stajger
fuente
no se llama al método delegado @Peter Stajger
Mansuu ...
4

Esto funcionó bien cuando necesitaba hacer que el texto se UITextViewajustara a un área específica:

// El texto ya debe agregarse a la subvista, o contentviewsize será incorrecto.

- (nulo) reduceFontToFit: (UITextView *) tv {
    UIFont * font = tv.font;
    doble pointSize = font.pointSize;

    while (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        pointSize - = 1.0;
        UIFont * newFont = [UIFont fontWithName: font.fontName tamaño: pointSize];
        tv.font = newFont;
    }
    if (pointSize! = font.pointSize)
        NSLog (@ "fuente hasta% .1f desde% .1f", pointSize, tv.font.pointSize);
}
Bill Cheswick
fuente
4

Aquí está la versión rápida de @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
Alnamrouti Fareed
fuente
66
La pregunta es realmente un lenguaje agnóstico. ¿Es realmente necesario regresar y escribir puertos rápidos para todas las respuestas a preguntas relacionadas con UIKit? Parece que eso hace una conversación ruidosa.
eremzeit
el problema de que la mayoría de estas preguntas tiene ningún lenguaje de programación específico para que lo encontrará en Google, incluso si la búsqueda de la lengua veloz
Fareed Alnamrouti
4

deshabilitar el desplazamiento

agregar constaints

y agrega tu texto

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

si lo usa UIScrollView, debe agregar esto también;

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

Para iOS 7.0, en lugar de configurar frame.size.heightel uso contentSize.height(que actualmente no hace nada) [textView sizeToFit].

Ver esta pregunta .

Stian Høiland
fuente
2

Usar UITextViewDelegate es la forma más fácil:

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

Espero que esto ayude:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
Dr. marty
fuente
¡Esto no funciona! Causa un error: "lvalue requerido como operando izquierdo de la asignación"
leviatán
Solo puedes asignar a textView.frame.
jweyrich
1

si alguna otra llega aquí, esta solución funciona para mí, 1 "Ronnie Liew" +4 "user63934" (Mi texto llega del servicio web): tenga en cuenta el 1000 (nada puede ser tan grande "en mi 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;

Y eso es ... Saludos

Alejo JM
fuente
1

La mejor manera que descubrí para cambiar el tamaño de la altura de UITextView de acuerdo con el tamaño del texto.

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

o puedes USAR

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

Para aquellos que desean que la vista de texto se mueva hacia arriba y mantenga la posición final

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

El único código que funcionará es el que usa 'SizeToFit' como en la respuesta de jhibberd anterior, pero en realidad no contestará a menos que lo llame en ViewDidAppear o lo conecte al evento de cambio de texto UITextView.

Mohammad Zekrallah
fuente
1

Basado en la respuesta de Nikita Took, llegué a la siguiente solución en Swift que funciona en iOS 8 con 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
fuente
1

Respuesta rápida: El siguiente código calcula la altura de su 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)))

Ahora puede establecer la altura de su textView en myTextHeight

RawMean
fuente
Lo sentimos, ¿qué significa? let attribute = [NSFontAttributeName: textView.text.font!] ¿Es realmente este código Swift sin errores?) ¿Quiso decir let attribute = [NSFontAttributeName: textView.font!]
Massmaker