ios objective-c uitableview

ios - ¿Cómo cambiar el tamaño de UITableViewCell para que se ajuste a su contenido?



objective-c (8)

Tengo una vista de UITableview con múltiples TableViewCells reutilizables. En una celda tengo un UITextView , que cambia su tamaño para ajustarse a su contenido. Ahora "solo" tengo que cambiar el tamaño del contentView de TableViewCell, para poder leer el texto while. Ya lo intente

cell2.contentView.bounds.size.height = cell2.discriptionTextView.bounds.size.height;

O:

cell2.contentView.frame = CGRectMake(0, cell2.discriptionTextView.bounds.origin.y, cell2.discriptionTextView.bounds.size.width, cell2.discriptionTextView.bounds.size.height);

En el método:

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

Pero no funcionará.

¿Alguien sabe como hacer esto?

Nuevo código:

@implementation AppDetail CGFloat height; … - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {… cell2.TextView.text = self.text; [cell2.TextView sizeToFit]; height = CGRectGetHeight(cell2.TextView.bounds); … } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { return 143; } if (indexPath.row == 1) { return height; } return 0; }


Agregar estos dos métodos al ViewController con UITableViewAutomaticDimension debería hacer el truco. Ha funcionado para mí cuando incrusté un UITextView dentro de un UITableViewCell con texto de longitud variable.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; }


Aquí hay una versión actualizada para iOS 7+ que es más limpia (sin método adicional)

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UIFont * font = [UIFont systemFontOfSize:15.0f]; NSString *text = [getYourTextArray objectAtIndex:indexPath.row]; CGFloat height = [text boundingRectWithSize:CGSizeMake(self.tableView.frame.size.width, maxHeight) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName: font} context:nil].size.height; return height + additionalHeightBuffer; }


Como dijo @Rob Norback, hay algo llamado UITableViewAutomaticDimension .

Para Swift, la forma más fácil de cambiar el tamaño del contenido de UITableViewCell sobre la marcha es simplemente agregar esto.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }


En el caso de la subvista UILabel en el UITableViewCell, realicé el cambio de tamaño automático de la etiqueta simplemente configurando las restricciones de la etiqueta (usando storyboard, Xcode 8.3.2).

Esto está funcionando ya que aparentemente el comportamiento predeterminado de la etiqueta y la celda es sizeToFit. Lo mismo debería funcionar para UITextView también.


Este hilo lleva bastante tiempo, pero en iOS 8 se introdujo UITableViewAutomaticDimension . Tiene que establecer restricciones desde la parte superior a la parte inferior de la celda como una vista de desplazamiento para que esto funcione. Pero después de eso, simplemente agregue el siguiente código a viewDidLoad() :

tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 122.0

Asegúrate de que tu altura estimada esté lo más cerca posible de la cosa real, de lo contrario obtendrás un poco de desplazamiento con errores.


Estoy a favor de esta solución de Jure.

  • Primero, establezca las restricciones de la vista de texto que se fijarán con su vista de supervisión (contentView de la celda en este caso).
  • Deshabilitar textView.scrollEnabled
  • Conjunto

    table.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44;

    Si finalmente, su código no funciona, entonces use esto en su lugar

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return 44; }

  • Implementar UITextViewDelegate esta manera:

    - (void)textViewDidChange:(UITextView *)textView { CGPoint currentOffset = self.tableView.contentOffset; [UIView setAnimationsEnabled:NO]; [self.tableView beginUpdates]; [self.tableView endUpdates]; [UIView setAnimationsEnabled:YES]; [self.tableView setContentOffset:currentOffset animated:NO]; }


Necesitas que implementes heightForRowAtIndexPath .

Digamos que los datos que se mostrarán en el textView se almacenan en una NSArray.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat cellheight = 30; //assuming that your TextView''s origin.y is 30 and TextView is the last UI element in your cell NSString *text = (NSString *)[textArray objectAtIndex:indexpath.row]; UIFont *font = [UIFont systemFontOfSize:14];// The font should be the same as that of your textView CGSize constraintSize = CGSizeMake(maxWidth, CGFLOAT_MAX);// maxWidth = max width for the textView CGSize size = [text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap]; cellHeight += size.height; //you can also add a cell padding if you want some space below textView }


Solo puede cambiar el tamaño de un UITableViewCell en tableView:heightForRowAtIndexPath: delegate method.

Debe estimar cuál será el tamaño del texto cuando se llame a ese método para cada fila cuando se cargue el tableView.

Esto es lo que hice para resolver el problema.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSString * yourText = self.myArrayWithTextInIt[indexPath.row]; // or however you are getting the text return additionalSpaceNeeded + [self heightForText:yourText]; } -(CGFloat)heightForText:(NSString *)text { NSInteger MAX_HEIGHT = 2000; UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, WIDTH_OF_TEXTVIEW, MAX_HEIGHT)]; textView.text = text; textView.font = // your font [textView sizeToFit]; return textView.frame.size.height; }

EDITAR

Si bien usé esta solución por un tiempo, encontré una más óptima que recomendaría usar, ya que no requiere asignar una vista de texto completa para que funcione, y puedo manejar un texto mayor a 2000.

-(CGFloat)heightForTextViewRectWithWidth:(CGFloat)width andText:(NSString *)text { UIFont * font = [UIFont systemFontOfSize:12.0f]; // this returns us the size of the text for a rect but assumes 0, 0 origin CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}]; // so we calculate the area CGFloat area = size.height * size.width; CGFloat buffer = whateverExtraBufferYouNeed.0f; // and then return the new height which is the area divided by the width // Basically area = h * w // area / width = h // for w we use the width of the actual text view return floor(area/width) + buffer; }