2010-11-21 10 views
42

Me gustaría tener una vista de tabla con un comportamiento similar a la aplicación de Contactos iPhone de Apple: una celda uitableview con uitextview adentro, de modo que cuando escribo en el uitextview, la uitextview aumenta su altura, y por lo tanto la uitableviewcell dinámicamente ajusta su altura ¡Busqué en toda la web, buscando solo soluciones parciales y falta de código de muestra!¿Cómo hacer una UITableViewCell con una UITextView adentro, que ajuste dinámicamente su altura, sobre la base de UITextView?

favor me ayude estoy desesperada

, Tony

Respuesta

0

Es necesario volver a la altura correcta en el método delegado heightForRowAtIndexPath.

+0

sí lo sé eso, pero no sé cómo implementar el "autoresize" de la vista de contenido y de la propia celda :-(¿Tiene algún código de muestra? Gracias. Tony – Tony

+0

Ah, ya veo. No tengo ningún código de muestra. Podría intente volver a cargar solo esa celda cuando el texto se actualice, por lo que la tabla vuelve a calcular la altura. Puede causar problemas porque el campo de texto también lo hace. – Rengers

37

En cuanto a esto, debe ser un poco complicado. Es necesario para calcular la altura de la Textview de forma dinámica y en base a la altura de la Vista de Texto, es necesario devolver la altura de la celda ..

Es muy fácil & algo difícil ..

Este es el código por el cual se puede calcular el tamaño de la cadena ....

en primer lugar obtener el tamaño de la cadena

NSString *label = @"Sample String to get the Size for the textView Will definitely work "; 
CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15] 
         constrainedToSize:CGSizeMake(320, 9999) 
          lineBreakMode:UILineBreakModeWordWrap]; 

over here .... 
NSLog(@"%f",stringSize.height); 

en segundo lugar dinámicamente crear el Textview en el cell..giving la stringSize.height

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    //if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    //} 

    NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section]; 

    NSString *string = [d valueForKey:@"Description"]; 
    CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap]; 

    UITextView *textV=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, stringSize.height+10)]; 
    textV.font = [UIFont systemFontOfSize:15.0]; 
    textV.text=string; 
    textV.textColor=[UIColor blackColor]; 
    textV.editable=NO; 
    [cell.contentView addSubview:textV]; 
    [textV release]; 

    return cell; 
} 


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section]; 
    NSString *label = [d valueForKey:@"Description"]; 
    CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15] 
          constrainedToSize:CGSizeMake(320, 9999) 
           lineBreakMode:UILineBreakModeWordWrap]; 

    return stringSize.height+25; 

} 

Después de dar tanto dolor a mis dedos, ...... Creo que esto es suficiente código & ... seguramente ayudará a resolver su problema ..

buena suerte

+1

esta respuesta aún no está completa, complétela – harshalb

+0

Para mí funciona perfectamente ... No vi nada perdido en él. Las sugerencias para cambios son bienvenidas ... –

+0

Creo que ha asignado accidentalmente un UILabel y lo ha asignado a la variable textV en lugar de asignar un UITextView real. – Shoerob

-1

se puede obtener el tamaño programmatically.According UITextView al tamaño, ajustar la altura de la celda utilizando la siguiente delegado

tableView:heightForRowAtIndexPath: 
12

Crear una costumbre UITableViewCell y añadir su UITextView a continuación de la célula entView.

En LayoutSubviews, establezca textView.frame en contentView.bounds de la celda (o haga otro diseño personalizado).

Cuando el contenido Textview cambian (descubierto a través de UITextViewDelegate), hacer dos cosas:

1) llamar [tableView beginUpdates]; [tableView endUpdates]; Esto obligará a la vista de tabla para volver a calcular la altura de todas las células (se llame tableView:heightForRowAtIndexPath:). Si su celda es la delegada de textView, entonces tendrá que descubrir cómo obtener un puntero a tableView, pero hay algunas maneras de lograrlo. O puede hacer que el delegado sea su controlador de vista ...

2) cuando se llama a tableView:heightForRowAtIndexPath: para esta celda, devuelva textView.contentSize.height. Puede obtener su celda desde aquí llamando al [tableView cellForRowAtIndexPath]; O si solo tiene una de estas celdas, coloque en ella un puntero en su viewController.

1

Finalmente lo puse en funcionamiento. El principal problema es cómo obtener el ancho correcto de la celda contentView. El ancho de codificación no funciona para todos los casos, ya que puede variar según el estilo de tabla simple/agrupada, los accesorios añadidos o el diseño de paisaje/retrato.La única forma de obtener el 100% de ancho correcto es preguntándolo desde el objeto de celda. Así que creo una celda directamente en heightForRowAtIndexPath y la almaceno en caché, luego esta celda en caché será devuelta por el método cellForRowAtIndexPath. Otro problema es cómo forzar a la celda a diseñar sus subvistas antes de que se use. Se puede hacer si agregamos temporalmente la celda al tableView y actualizamos el marco de la celda con el ancho de tabelView. Después de eso, todas las subvistas se presentarán de la manera correcta. Here es cómo lo conseguí trabajando en mi biblioteca TableKit.

-2

Chicos esto es realmente genial, pero puede usar tableview: didSelectRowForIndexPath: para agregar el UITextView a la celda como subvista cuando el usuario lo toca, funciona muy bien ya que solo necesita usar 1 UITextView que puede reutilizar y no interferirá con la mesa que recibe toques! Suelta cuando haya terminado.

Detalles? ¡solo pregunta!

0

Prueba el siguiente código:

CGSize constraintSize; 
constraintSize.height = MAXFLOAT; 
constraintSize.width = yourTextView.frame.size.width; 
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 
             [UIFont fontWithName:@"yourFontName" size:yourFontSize], NSFontAttributeName, 
             nil]; 

CGRect frame = [yourTextView.text boundingRectWithSize:constraintSize 
            options:NSStringDrawingUsesLineFragmentOrigin 
           attributes:attributesDictionary 
            context:nil]; 

CGSize stringSize = frame.size;//The string size can be set to the UITableViewCell 
3

El único problema que encontré con la respuesta aceptada es que estamos asignando el UITextView cada uno y cada una. Descubrí que esto plantea problemas al tipear en la vista y hacer que el texto se actualice de inmediato y también mantener la vista como primera respuesta. Cuando intenté volver a cargar la celda con la nueva altura, intentaría agregar un nuevo textView.

Debido a esto encontré un método ligeramente diferente para lograr el mismo objetivo. Esperemos que esta toma diferente pueda ayudar a las personas que están luchando por implementar el código anterior.

1) En el archivo de cabecera definir una variable para la altura del texto y el TextView:

UITextView * _textView; 
NSInteger _textHeight; 

Configuración de una variable significa que podemos cargar la vista a ser una cierta altura si estamos cargando el texto en textView y también reduce la complejidad.

2) cargar la vista de texto y añadirlo a nuestra celda

_textView = [[UITextView alloc] init]; 
_textView.delegate = self; 
_textView.returnKeyType = UIReturnKeyDone; 
_textView.font = [UIFont fontWithName:@"Helvetica" size:16]; 

if (![_user metaStringForKey:bBioKey].length) { 
    _textView.text = @"Placeholder text"; 
    _textView.textColor = [UIColor lightGrayColor]; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView_ cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (indexPath == 0) { // Add logic to choose the correct cell 

     if (_textView.superview != cell) { 

      [cell addSubview:_textView];  

      _textView.keepTopInset.equal = KeepRequired(7); 
      _textView.keepBottomInset.equal = KeepRequired(7); 
      _textView.keepRightInset.equal = KeepRequired(10); 
      _textView.keepLeftInset.equal = KeepRequired(70); 
      } 
     } 
    } 
} 

Usando keeplayout nos ha permitido mantener nuestro campo de texto para permanecer siempre la misma altura que la célula. Además, solo agregamos nuestra UITextView una vez.

3) Agregue el código para calcular la altura del texto

- (NSInteger)getHeightOfBio: (NSString *)text { 

    UILabel * gettingSizeLabel = [[UILabel alloc] init]; 
    gettingSizeLabel.font = [UIFont fontWithName:@"Helvetica" size:16]; 
    gettingSizeLabel.text = text; 
    gettingSizeLabel.numberOfLines = 0; 
    CGSize maximumLabelSize = CGSizeMake(240, 9999); // this width will be as per your requirement 

    CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize]; 

    return expectedSize.height; 
} 

He probado muchos y encontró que esto funcione lo mejor

4) Añadir un poco de lógica en la altura de la celda para hacer uso de esta:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (indexPath.row == 0) { // Set the height for our changing textView 

     return 30 + [self getHeightOfBio:_textView.text]; 
    } 

    return 44; 
} 

obvio que necesitamos un poco más de altura que nuestra altura del texto por lo que añade una cantidad amortiguación adicional que puede ser experimentado con.

5) actualizar la vista cada vez que un personaje se escribe para comprobar si tenemos que aumentar el tamaño:

- (void)textViewDidChange:(UITextView *)textView { 

    if ([self getHeightOfText:textView.text] != _textHeight) { 

     _textHeight = [self getHeightOfText:textView.text]; 

     [self.tableView beginUpdates]; 
     [self.tableView endUpdates]; 
    } 
} 

En esta sección obtenemos la altura del texto cada vez que el usuario escribe.

Luego, utilizamos nuestro valor almacenado y comparamos el valor actual con el valor almacenado. Obviamente, si son iguales, no tiene sentido refrescar la vista. Si son diferentes, actualizamos el valor y luego actualizamos nuestra tabla.

Este bit encontré una buena respuesta en stackOverflow que muestra cómo podemos actualizar solo las alturas de la tabla en lugar de la celda misma. ¿Por qué refrescar la celda cuando no es necesario? Esto significa que una vez que esto se llama la altura de la celda se actualiza y aumenta muy bien.

De todos modos, encontré que esto funcionó muy bien y era lo suficientemente simple como para poder juntarlo o tomar partes diferentes y ponerlo en códigos de otras personas.

Apoyos a la respuesta aceptada que fue saqueada por varias piezas en el camino, pero también espero que esta respuesta ayude a algunas personas que están teniendo las mismas dificultades que yo tuve.

1

edito respuesta TomSwift que es la mejor manera de hacerlo:

aquí es mi código de celda (en Swift)

class CommentaireTextViewCell: UITableViewCell,UITextViewDelegate { 

@IBOutlet weak var textViewCom: UITextView! 
weak var parentTableView:UITableView? 

@IBOutlet weak var constraintTextViewTopMargin: NSLayoutConstraint! 
@IBOutlet weak var constraintTextViewHeight: NSLayoutConstraint! 
@IBOutlet weak var constraintTextViewBottomMargin: NSLayoutConstraint! 
override func awakeFromNib() { 
    self.textViewCom.delegate = self; 
} 

func textViewDidChange(textView: UITextView) { 
    self.parentTableView?.beginUpdates(); 
    self.parentTableView?.endUpdates(); 
} 

func getHeight() -> CGFloat 
{ 
    constraintTextViewHeight.constant = self.textViewCom.contentSize.height; 
    // cell height = textview marge top+ textview height+ textView Marge bottom 
    return constraintTextViewTopMargin.constant+constraintTextViewHeight.constant+constraintTextViewBottomMargin.constant+8 
    // add 8 because it seems to have an inset inside the textView 
} 

override func setSelected(selected: Bool, animated: Bool) { 
    self.textViewCom.becomeFirstResponder(); 
} 
} 

para la explicación, la vista de tabla celular es un propertie débil la celda, así que puedo decir que actualice el diseño cuando el usuario ingrese el texto. La altura de la celda es la suma de la parte superior a la limitación contentView, su restricción a la parte inferior y la contentView textView.contantSize.height que también es igual a la constante de altura Textview

enter image description here

+0

Cómo llamar a getHeight()? – Satyam

Cuestiones relacionadas