¿Cómo forzar uitableview para cambiar el tamaño de una celda (después de desactivar una restricción de altura)?

Estoy intentando poner un UITableViewCell extensible tocando un button.

Estoy usando las restricciones para obligar al UITextView dynamic a decirle a UITableViewCell su nueva altura. (usando autolayout y UITableViewAutomaticDimension )

Esto funciona como se esperaba sin el button: La altura de UITableViewCell depende de la altura de UITableViewCell .

Tener una restricción en UITextView para maximizar el tamaño de la celda, al tocar el button (la celda está queuepsada), quiero eliminar la restricción de altura a UITextView (que está limitando la altura de la celda) y actualizar la celda en consecuencia. Aquí está el método extend:

 -(void)extendCellWasTapped:(UITableViewCell*)senderCell{ MAFollowingPostTableViewCell *cell = (MAFollowingPostTableViewCell*)senderCell; NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; if (![self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) { [self.arrayExtendedTitlesAtIndexPaths addObject:indexPath]; } if ([self.tableView.indexPathsForVisibleRows containsObject:indexPath] ) { dispatch_async(dispatch_get_main_queue(), ^(void){ [NSLayoutConstraint deactivateConstraints:@[cell.constraintTextViewHeight]]; // CGPoint offset = self.tableView.contentOffset; [self.tableView beginUpdates]; [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; [self.tableView endUpdates]; // I would like to minimize the animations as well here.. but thats another //problem // [self.tableView.layer removeAllAnimations]; // [self.tableView setContentOffset:offset animated:NO]; // [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; }); } } 

Si presiono el button y luego se desplaza a una celda similar, ya está expandida. Entonces me falta algo aquí. Ya intenté hacer [cell updateConstraints] después de desactivar la restricción, pero no funciona.

ACTUALIZAR

Al principio, el button no aparece por alguna razón. Y noté que (con el mismo código) si me desploop hacia abajo y luego hacia arriba, el button aparece y, si trato de extenderlo, funciona.

ACTUALIZAR

Este es mi UIViewController:

Tenga en count que el button extender no está allí, pero una vez que me desploop hacia abajo / hacia arriba aparece aparece y extiende la celda una vez que presiono el button extender.

ACTUALIZAR

Noté que cuando se está calculando textSize (para ver si la celda es extensible o no), al principio, textView es más ancho que su estado final. Y estoy realizando esta comprobación en cellForRowAtIndexPath:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MAPostTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier forIndexPath:indexPath]; cell.delegate = self; cell.selectionStyle = UITableViewCellSelectionStyleNone; MAPostFollowing *post = (MAPostFollowing*)[self.arrayPosts objectAtIndex:indexPath.section]; cell.textViewTitle.textContainer.lineBreakMode = NSLineBreakByWordWrapping; NSString *title = [post.post title]; [cell.textViewTitle setText:title]; UIButton * buttonExtend = [cell buttonExtend]; if ([self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) { cell.constraintTextViewHeight.active = NO; if (![buttonExtend isHidden]) { buttonExtend.hidden = YES; buttonExtend.userInteractionEnabled = NO; } }else{ cell.constraintTextViewHeight.active = YES; NSLog(@"index %li", (long)indexPath.row); BOOL b = ![self isTitleExtendable:title forTextView:cell.textViewTitle]; // Checks if the current text view is able to fit the title. If not, it will show the buttonExtend buttonExtend.hidden = b; buttonExtend.userInteractionEnabled = !b; } } ... 

Entonces, en la primera ejecución (antes de desplazarse), el [self isTitleExtendable: title forTextView: cell.textViewTitle]; no devuelve el valor deseado ya que textView no tiene el ancho correcto cuando se está calculando textSize.

Por lo tanto, creo que tengo las siguientes opciones: – obligar a textViewTitle a actualizarse después de que haya cambiado el layout (calculando así correctamente el estado extensible de la IU) – vuelva a verificar el estado extensible de la interfaz de usuario una vez que textViewTitle cambie el ancho

ACTUALIZAR

En el método prepareForReuse, textViewTitle aún tiene un marco más amplio. En el método layoutSubviews, de hecho, tiene un pequeño marco. El desafío aquí es que es llamado más a menudo, y me da casos falsos (el button se muestra cuando no debería)

Esto es lo que estaba experimentando:

 -(void)layoutSubviews{ [super layoutSubviews]; BOOL b = [self isTitleExtendable:self.textViewTitle.text forTextView:self.textViewTitle]; self.buttonExtend.hidden = !b; self.buttonExtend.userInteractionEnabled = b; if (!b) { NSLog(@"Button hidden YES UserInteraction NO"); }else{ NSLog(@"Button hidden NO UserInteraction YES"); } NSLog(@"textViewTitle layout %f",self.textViewTitle.frame.size.width); } 

Para hacer tal cosa, no debe confiar en la restricción, pero en tableView(_:heightForRowAtIndexPath:) solo tiene que dar la altura correcta según el context.

Al presionar su button se desencadenaría un cambio para que tableView(_:heightForRowAtIndexPath:) devuelva un valor diferente para su celda que extienda.

Y justo después de hacer este disparador, simplemente haz lo siguiente:

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

sin nada entre ellos, activará la "animation natural" de UITableView y hará exactamente lo que quiera

¿ Te olvidas de eliminar indexpath de self.arrayExtendedTitlesAtIndexPaths ?

 if (![self.arrayExtendedTitlesAtIndexPaths containsObject:indexPath]) { [self.arrayExtendedTitlesAtIndexPaths addObject:indexPath]; } else { [self.arrayExtendedTitlesAtIndexPaths removeObject:indexPath]; } 

Si el button no está allí y mientras se desplaza vuelve a mostrarse seguramente tiene un problema de reutilización.

Es probable que decidas mostrar u ocultar el button en cellForRowAtIndexPath: Si tiene una condición, intente mostrar este button siempre, y si esto funciona como se esperaba, entonces oculte un button dentro de una celda siempre que esta restricción esté o no presente. El método correcto es prepareForReuse dentro de la subclass UITableViewCell .

Llamada [cell layoutSubviews]; Una vez que se completen sus cambios.